0

I'm having one issue that is how to catch OptimisticLockException in web layer (.war code) when it is raised by the EJB layer.

We are using JEE5, GlassFishV2.1 and JPA (with TopLinks)and Container Managed Transactions.But when the dirty read occur due to trnasaction by another concurrent user on the same entity.It gives Transaction.RollBackException at the war layer which is actually caused by OptimisticLockException.But i am unable to catch OptimisticLockException at war side.

I found on internet
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

that use of em.flush on ejb side and then we can catch and throw some custom exception to war. but I think em.flush will refresh all database, is it an expensive operation or not?

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

throw ole;
}

My opinion is not to call em.flush as 90% of cases there will be no OptimisticLockException and to catch the EJBException in the .war and then retry it. Is there a better option?

try{ // some code } catch (EJBException ex) {

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

1 回答 1

1

你也可以。从技术上讲,flush() 并不是一项昂贵的操作,因为它在写入数据库时​​所做的工作不再需要由提交完成,因此没有额外的数据库访问,也不会“刷新所有数据库”。但是,flush() 确实有一些开销,更改将计算两次,一次用于刷新,一次用于提交,一次用于提交。根据您的更改策略和托管对象的数量,这确实是有成本的。Flush 还需要将托管对象放回被跟踪的托管状态,这也有一些成本,但与数据库访问成本相比,通常较小。

请注意,在提交期间可能会发生除锁定错误之外的其他错误,因此即使您使用刷新来捕获锁定错误,您仍然需要在您的战争中使用代码来处理其他失败原因,因此不要使用刷新,而只需一般事务失败错误处理可能是最好的解决方案。如果你想对锁错误做一些特殊的事情,你应该能够通过链找到原因中的异常,但是在重试操作时要小心,你正在锁定是有原因的,所以应该将错误报告给用户并让他们重试操作。

于 2010-09-29T13:57:51.687 回答