Как поймать OptimisticLockException в веб-слое

У меня есть одна проблема, которая заключается в том, как перехватить OptimisticLockException в веб-слое (код.war), когда он вызывается слоем EJB.

Мы используем JEE5, GlassFishV2.1 и JPA (с TopLinks) и транзакции, управляемые контейнером. Но когда происходит грязное чтение из-за trnasaction другим параллельным пользователем на той же сущности. Это дает Transaction.RollBackException на уровне войны, который фактически вызывается by OptimisticLockException. Но я не могу поймать OptimisticLockException на стороне войны.

Я нашел в интернете
http://books.google.com/books?id=fVCuB_Xq3pAC&pg=PA292&dq=OptimisticLockException++Collision+Exception&hl=en&ei=0A6jTI3nN5DQccbO5MAB&sa=X&oi=book_result&ct=result&resnum=1&ved=0CCgQ6AEwAA

это использование em.flush на стороне ejb, и тогда мы можем поймать и выбросить какое-то пользовательское исключение для войны. но я думаю, что em.flush обновит всю базу данных, это дорогая операция или нет?

try{
   //some enitity
   em.flush()
  }
catch(OptimisticLockException ole){

throw ole;
}

Мое мнение не в том, чтобы вызывать em.flush, так как в 90% случаев не будет OptimisticLockException, а чтобы перехватить EJBException в.war, а затем повторить попытку. Есть ли лучший вариант?

try {// некоторый код} catch (EJBException ex) {

      if (ex.getCausedByException().getCause().toString().
          indexOf("javax.transaction.RollbackException")!= -1){
               // do work
          }     
      }
   }

1 ответ

Вы могли бы сделать либо. flush() технически не является дорогостоящей операцией, так как работа, которую она выполняет при записи в базу данных, больше не должна выполняться коммитом, поэтому нет дополнительного доступа к базе данных и она не "обновляет всю базу данных". У flush () есть некоторые накладные расходы, однако изменения будут вычислены дважды, один раз для flush и один раз для commit, а один раз - для commit. В зависимости от вашей политики изменения и количества управляемых объектов, это имеет свою стоимость. Flush также должен вернуть управляемые объекты в отслеживаемое управляемое состояние, которое также имеет некоторую стоимость, но, как правило, незначительное по сравнению со стоимостью доступа к базе данных.

Обратите внимание, что во время фиксации могут возникать другие ошибки, кроме ошибки блокировки, поэтому даже если вы используете сброс для обнаружения ошибки блокировки, вам все равно нужен код в вашей войне для обработки других причин сбоя, поэтому не используйте сброс и просто Общей ошибкой транзакции обработки может быть лучшее решение. Если вы хотите сделать что-то особенное для ошибки блокировки, вы должны быть в состоянии найти исключение в причине по цепочке, но будьте осторожны, просто повторяя операцию, вы блокируете по причине, поэтому, вероятно, следует сообщить об ошибке в пользователь и попросите их повторить свою работу.

Другие вопросы по тегам