Reputation: 61
When using a Galera, I am getting - works even fine, when pointing to a remote DB (not just local).
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)
I get triggered via CDI event, fired when something arrives on a JMS queue, in the code I perform a READ/FIND, like:
entityManager.find(getType(), id, LockModeType.PESSIMISTIC_WRITE);
than, I update the object and its nested collection, than I run an "update", which boils down to this (inside the DAO's update()):
this.lock(myobj);
this.update(myobj);
Where lock() does:
entityManager.lock(entity, LockModeType.PESSIMISTIC_WRITE);
and update()
combines:
entityManager.merge(entity);
entityManager.flush();
It's only happening when I change my JBoss datasource config to point to a Galera URL - going directly to one (remote) DB -> no problem
Upvotes: 2
Views: 1782
Reputation: 153800
I don't understand why do you lock twice:
First, you are locking using the FOR UPDATE
clause:
entityManager.find(getType(), id, LockModeType.PESSIMISTIC_WRITE);
Second, you lock the myobj
:
this.lock(myobj);
I noticed that update Anti-Pattern. If you have a managed entity, you don't need any explicit update. The merge
operation is meant for detached entities.
Now, related to the deadlock. You need to check which rows are causing the deadlock. Most likely that during flush
, Hibernate executes an UPDATE on the child entities as well.
Since Galera uses an optimistic locking approach to resolving conflicts across multiple Master nodes, the deadlock can only occur if two transactions hold locks and try to acquire each other transaction locks. So, there must be at least two transactions involved here. Check out the logs to see the contention.
Upvotes: 2