Question

If I open a transaction, and put code that is potentially going to throw OLE in a try-catch block, will I have to restart the transaction? My answer is yes, but I can't seem to find any confirmation out there...

My code basically looks like this:

//start a hibernate transaction here
try
{
   //do things that are very likely to throw OLE
}
catch (Exception exc) 
{
   //just log it and do nothing else
}

//do something else that needs a hibernate session here (*)

So when I'm at (*), it looks like I would need to check whether or not the transaction is still active?

Was it helpful?

Solution

From: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html#transactions-demarcation-exceptions

If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable. Ensure that the Session will be closed by calling close() in a finally block.

And from: http://docs.oracle.com/javaee/6/api/javax/persistence/OptimisticLockException.html

Thrown by the persistence provider when an optimistic locking conflict occurs. This exception may be thrown as part of an API call, a flush or at commit time. The current transaction, if one is active, will be marked for rollback.

So yes, you should close the session, then try again.

OTHER TIPS

This is an extract of what you can find in the JPA specification regarding OptimisticLockException:

  • the version check is done when writing changes to DB, hence the exception will normally be thrown at commit time
  • it always causes the transaction to be marked for rollback
  • if you want to catch and handle the exception, call flush() to force DB writes to occur earlier
  • the exception provides an API to return the object that caused the exception
  • it is typically handled by refreshing/reloading stale objects and retrying the transaction

For the sake of completeness, here is a copy of the relevant section from the specification:
(I cannot provide a specific link, as the document is only available in .pdf format here).

3.4.5 OptimisticLockException

Provider implementations may defer writing to the database until the end of the transaction, when consistent with the lock mode and flush mode settings in effect. In this case, an optimistic lock check may not occur until commit time, and the OptimisticLockException may be thrown in the "before completion" phase of the commit. If the OptimisticLockException must be caught or handled by the application, the flush method should be used by the application to force the database writes to occur. This will allow the application to catch and handle optimistic lock exceptions.

The OptimisticLockException provides an API to return the object that caused the exception to be thrown. The object reference is not guaranteed to be present every time the exception is thrown but should be provided whenever the persistence provider can supply it. Applications cannot rely upon this object being available.

In some cases an OptimisticLockException will be thrown and wrapped by another exception, such as a RemoteException, when VM boundaries are crossed. Entities that may be referenced in wrapped exceptions should implement Serializable so that marshalling will not fail.

An OptimisticLockException always causes the transaction to be marked for rollback.

Refreshing objects or reloading objects in a new transaction context and then retrying the transaction is a potential response to an OptimisticLockException.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top