2017-02-15 224 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

我同意。嘗試對加萊拉使用「悲觀」似乎是「錯誤的」。 –