как отловить OptimisticLockException в веб-слое - PullRequest
0 голосов
/ 29 сентября 2010

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

Мы используем JEE5, GlassFishV2.1 и JPA (с TopLinks) и транзакции, управляемые контейнером. Но когда происходит грязное чтение из-за trnasaction другим параллельным пользователем в той же сущности. Это дает Transaction.RollBackException на уровне войны, который на самом деле вызвано 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#v=onepage&q=OptimisticLockException%20%20Collision%20Exception&f=false

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

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

throw ole;
}

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

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

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

1 Ответ

1 голос
/ 29 сентября 2010

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

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

...