Подтвердить что ты не робот

Исключение спящего режима LockAcquisitionException: не удалось обновить

В моем приложении я использую Java, Hibernate (аннотации) и mySQL. Он работает отлично в большинстве случаев, но эта ошибка происходит иногда:

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)

Самая подозрительная строка в Analysis.java:

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

Что я сделал, это захватить строку с помощью dbPersonId и обновить/изменить содержимое строки по мере необходимости. Например:

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

Я угадываю что-то не так с LockOptions и Я пытался использовать разные блокировки, такие как NONE, UPGRADE... но все равно не повезло.

Самая расстроенная вещь - я даже не могу воспроизвести эту ошибку вручную. Это происходит только раз, когда Analysis.java вызывается несколько раз.

Я знаю, что сеанс не является потокобезопасным, но я не уверен, связано ли это с этим.

Любая идея была бы оценена, спасибо вам большое!

4b9b3361

Ответ 1

Поскольку он использует опцию блокировки READ, я улавливаю исключение, давайте потоку спящий некоторое время, а затем попытаемся снова получить блокировку, которая решает проблему:

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;
     }