2017-02-15 68 views
1

当使用Galera时,当指向一个远程数据库(不仅仅是本地)时,我得到了 - 工作得很好。死锁只与Galera MYSQL集群

Caused by: 
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: 
Deadlock found when trying to get lock; try restarting transaction 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native 
Method) [rt.jar:1.7.0_85] 
    at 
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAcc 
essorImpl.java:57) [rt.jar:1.7.0_85] 
    at 
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstr 
uctorAccessorImpl.java:45) [rt.jar:1.7.0_85] 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526) [rt.jar:1.7.0_85] 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
    at com.mysql.jdbc.Util.getInstance(Util.java:386) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1064) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2618) 
    at com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1654) 
    at org.jboss.jca.adapters.jdbc.local.LocalManagedConnection.commit(LocalManagedConnection.java:96) 

我得到通过CDI事件,当事情到达JMS队列,在我进行READ /找到,如代码发射触发:

entityManager.find(getType(), id, LockModeType.PESSIMISTIC_WRITE); 

比,我更新的对象和它的嵌套集,比我跑的 “更新”,这归结为(DAO的更新()内):

this.lock(myobj); 
this.update(myobj); 

凡锁()的作用:

entityManager.lock(entity, LockModeType.PESSIMISTIC_WRITE); 

update()结合:

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

当我改变我的JBoss数据源配置为指向加莱拉URL这只是发生了 - 直接将一个(远程)DB - >没问题

回答

1

我不明白你为什么锁两次:

  1. 首先,您使用的是FOR UPDATE条款锁定:

    entityManager.find(getType(), id, LockModeType.PESSIMISTIC_WRITE); 
    
  2. 其次,你锁定myobj

    this.lock(myobj); 
    
  3. 我注意到,更新反模式。如果您有一个托管实体,则不需要任何明确的更新。 merge操作适用于分离的实体。退房this article for more details

现在,与死锁有关。您需要检查哪些行导致了死锁。最有可能的是,在flush期间,Hibernate也在子实体上执行UPDATE。

由于Galera使用乐观锁定方法来解决跨多个主节点的冲突,只有两个事务处理锁并尝试获取每个其他事务锁时才会发生死锁。所以,这里至少要涉及两笔交易。查看日志以查看争用情况。

+0

我同意。尝试对加莱拉使用“悲观”似乎是“错误的”。 –