【问题标题】:Hibernate Transactions and Concurrency Using attachDirty (saveOrUpdate)使用 attachDirty (saveOrUpdate) 的休眠事务和并发
【发布时间】:2021-02-21 13:18:00
【问题描述】:

我有以下情况,其中attachDirty saveOrUpdate() 总是在突发调用事务注释方法时尝试持久化实体。

有没有办法避免这种违反主键约束的异常?我认为如果实体尚未创建,saveOrUpdate() 将持续存在,否则更新它。

我使用 ..orUpdate() 而不是 persist() 作为处理这些突发的方法。

实际上没有数据损坏。因为第一个saveOrUpdate() 确实根据需要为每个实体保存了一条记录。由于违反主键约束,其他持久化被数据库拒绝。

我研究了乐观和悲观锁定。我了解到这些工作是在获取现有记录后进行的。这里的实体是新的,而不是现有的。

如何以更好的方式解决这个问题?

【问题讨论】:

    标签: spring spring-boot hibernate concurrency


    【解决方案1】:

    为什么异常是一个问题,你不能忽略它吗?如果您的数据库支持“upsert”,理论上您可以通过在实体上添加以下注释来使用它:

    @org.hibernate.annotations.SQLInsert (sql = "INSERT INTO message_user (user_id) VALUES (?) ON CONFLICT DO NOTHING")
    

    【讨论】:

    • 我个人对这个例外没有问题。正在阅读日志的人会这样做:p 这正是我所需要的。它适用于 postgresSQL。现在我必须找到一种方法让它也适用于 Oracle。谢谢!
    • 您可以使用 Oracle 的 MERGE 语句,但您不能只捕获异常并忽略它以避免记录吗?
    • 我试图用 try catch 包裹.attachDirty(...)。该异常似乎在其他级别被触发(我认为在 @Transactional 注释方法的末尾)。我不知道如何抓住它。你 ?如果是,请分享一些提示或资源。
    • 刷新更改时抛出异常。如果你不手动调用entityManager.flush,Hibernate 通常会在提交之前刷新。所以 try-catch 必须绕过同花顺调用。
    猜你喜欢
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2014-09-20
    • 1970-01-01
    相关资源
    最近更新 更多