13

In my application I am using Java ,Hibernate(Annotations) and mySQL. It's working fine most of the time, but this error happens occasionally:

SEVERE: Could not synchronize database state with session
org.hibernate.exception.LockAcquisitionException: could not update: [myPack.Analysis$TestRun#5191]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:107)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2596)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2478)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2805)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:114)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:180)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at myPack.Analysis.fileHelper(Analysis.java:977)
    at myPack.Analysis.dirHelper(Analysis.java:702)
    at myPack.Analysis.dirHelper(Analysis.java:714)
    at myPack.Analysis.dirHelper(Analysis.java:714)
    at myPack.Analysis.dirHelper(Analysis.java:714)
    at myPack.Analysis.dirHelper(Analysis.java:714)
    at myPack.Analysis.dirHelper(Analysis.java:711)
    at myPack.Analysis.parseLog(Analysis.java:682)
    at myPack.Analysis.main(Analysis.java:614)

The most suspicious line in Analysis.java is:

dbPerson = (Person) session.get(Person.class, dbPersonId, LockOptions.READ);

What I did is grab the row with the dbPersonId and update/change the row contents as needed. For example:

dbPerson.Name = "Jack";
dbPerson.Age ++;
session.saveOrUpdate(dbPerson);

I am guessing something's wrong with the LockOptions and I tried using different lockoptions such as NONE, UPGRADE... but still no luck.

The most frustrated thing is I can't even reproduce this error manually. It only happens once a while when Analysis.java are called multiple times.

I know session is not thread-safe, but I am not sure whether this is related to that.

Any idea would be appreciated, thank you very much!

John Powel
  • 1,394
  • 3
  • 17
  • 30
  • I don't know what issue will it raise if I remove `LockOptions`, but maybe there's no point to get a lock in the first place? – John Powel Oct 10 '12 at 21:14
  • 1
    Maybe a clue in this issue? http://stackoverflow.com/questions/2596005/working-around-mysql-error-deadlock-found-when-trying-to-get-lock-try-restarti (It may be Perl related rather than Java, but the answer is generically applicable to MySQL) – Stewart May 23 '13 at 19:04

1 Answers1

3

Since it is using a READ lock option, I catch the exception ,let the thread sleep for a while and then try to acquire the lock again, which solves the problem:

try {
  dbPerson = (Person) session.get(Person.class, dbPersonId, LockOptions.READ);
} catch (RuntimeException e) {
  if (e instanceof LockAcquisitionException) {
    try {
      Thread.sleep(15000);
      dbPerson = (Person) session.get(Person.class, dbPersonId, LockOptions.READ);                      
     } else {
      throw e;
     }
John Powel
  • 1,394
  • 3
  • 17
  • 30