【问题标题】:Spring @Transactional DeadlockSpring @Transactional 死锁
【发布时间】:2011-12-18 08:31:16
【问题描述】:

我有以下设置。

  • 春季 3.0.5
  • 休眠 3.5.6
  • MySql 5.1

要通过 Hibernate 在数据库中保存记录,我有以下工作流程

  1. 将 JSON {id:1,name:"test",children:[...]} 发送到 Spring MVC 应用程序并使用 Jackson 将其转换为对象图(如果它是现有实例,则 JSON 具有数据库集中记录的正确 ID

  2. 通过服务层调用将对象保存在数据库中(详情如下)

    • 服务层接口SomeObjectService的save函数上面有@Transactional注解,有readOnly=false和PropagationREQUIRED

    • 这个服务层的实现SomeObjectServieImpl调用DAO保存 方法

    • DAO 通过调用 hibernate 的合并来保存新数据,例如hibernateTempate().merge(someObj)

    • hibernate merge首先通过SELECT从数据库加载对象

    • 我有一个连接到 spring 的 EntityListener(我使用了这种技术 Spring + EntityManagerFactory +Hibernate Listeners + Injection)并监听 @PostLoad

    • 1234563 /strong> 但在合并时也会被调用)
  3. LockingServie 有一个函数lock(someObj,userId),它也用@Transactional 注释,带有readOnly=falseREQUIRED

  4. 通过调用Query query = sess.createQuery("update someObj set lockedBy=:userId"); 进行更新,然后 query.executeUpdate();

  5. merge 加载数据后,它开始更新 someObject 并插入相关子项(发生死锁的地方)

  6. 将 JSON 结果(这也包括新创建的对象 ID)返回给客户端。

问题在我看来是第一个

  1. 记录被加载到事务中
  2. 然后在另一个(内部)事务中更改
  3. 然后应该使用外部事务的数据再次更新,但由于它被锁定而无法更新。

我可以通过 MySQL 看到

SHOW OPEN TABLES 

子表(对象图的一部分)被锁定。

有趣的事实是,死锁不会发生在 someObj 表上,而是发生在代表孩子的表上。

我有点迷路了。任何帮助都非常受欢迎。

顺便说一句,isolation 级别可以让我摆脱这个问题吗?

【问题讨论】:

    标签: mysql spring deadlock spring-transactions


    【解决方案1】:

    我最终使用了@Bozho 的HibernateExtendedJpaDialect

    这里解释了>> Hibernate, spring, JPS & isolation - custom isolation not supported

    将隔离设置为 READ_UNCOMMITED

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation=Isolation.READ_UNCOMMITTED)
    public Seizure merge(Seizure seizureObj);
    

    我知道这不是一个很好的解决方案,但至少这解决了我的问题。

    如果有人想要详细说明,请询问...

    【讨论】:

      【解决方案2】:

      我不知道问题的解决方案,但我不会有事务锁定方法。如果您需要手动锁定某些内容,请在另一个事务服务方法中进行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-19
        • 1970-01-01
        • 2021-07-11
        • 2019-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多