Java 仅在Galera MYSQL集群中死锁

Java 仅在Galera MYSQL集群中死锁,java,mysql,hibernate,locking,galera,Java,Mysql,Hibernate,Locking,Galera,当使用Galera时,当指向远程数据库(而不仅仅是本地数据库)时,我的工作甚至很好 我通过CDI事件触发,当某个东西到达JMS队列时触发,在代码中执行读取/查找,如: entityManager.find(getType(), id, LockModeType.PESSIMISTIC_WRITE); 然后,我更新对象及其嵌套集合,然后运行“更新”,这可以归结为(在DAO的update()中): 其中lock()用于: 和update()组合: entityManager.merge(entit

当使用Galera时,当指向远程数据库(而不仅仅是本地数据库)时,我的工作甚至很好

我通过CDI事件触发,当某个东西到达JMS队列时触发,在代码中执行读取/查找,如:

entityManager.find(getType(), id, LockModeType.PESSIMISTIC_WRITE);
然后,我更新对象及其嵌套集合,然后运行“更新”,这可以归结为(在DAO的update()中):

其中lock()用于:

update()
组合:

entityManager.merge(entity);
entityManager.flush();

只有当我将JBoss数据源配置更改为指向Galera URL时才会发生这种情况-直接指向一个(远程)DB->没问题

我不明白为什么要锁定两次:

  • 首先,使用
    FOR UPDATE
    子句锁定:

     entityManager.find(getType(), id, LockModeType.PESSIMISTIC_WRITE);
    
  • 第二,锁定
    myobj

     this.lock(myobj);
    
  • 我注意到更新反模式。如果您有一个托管实体,则不需要任何显式更新。该操作适用于分离的实体

  • 现在,关于僵局。您需要检查导致死锁的行。很可能在
    刷新期间,Hibernate也会对子实体执行更新

    由于Galera使用乐观锁定方法来解决多个主节点之间的冲突,因此只有当两个事务持有锁并试图获取彼此的事务锁时,才会发生死锁。因此,这里必须至少涉及两项交易。查看日志以查看争用。

    我同意。试图对Galera使用
    悲观的
    似乎是“错误的”。
    
    entityManager.merge(entity);
    entityManager.flush();
    
     entityManager.find(getType(), id, LockModeType.PESSIMISTIC_WRITE);
    
     this.lock(myobj);