Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retry a service method upon getting an OptimisticLockException with JPA and Hibernate

I have had some problems with dirty writes in hibernate. I have added @version fields so that I can see if I am writing to an out of date table. This has meant that I now have lots of boilerplate code that does

try {
   tryWriteToTable();
} catch (PersistenceExcepton) {  //subclasss of OptimisiticLockException
   try {
      tryWriteToTable();
   } catch (PersistenceExcepton) {
       //dont try again - something seriously wrong
   }
}  

I am using Spring and wondered if there is anything in that which will allow me to define this pattern. Something that will allow me to repeat if there is an exception. Other than Spring is there anything else I could use in order for me to avoid all this ugly boilerplate code.

I would like something like this

@TryTwice
private void tryWriteToTable() ....


 

Thanks

like image 420
RNJ Avatar asked Sep 29 '13 08:09

RNJ


People also ask

How do I resolve OptimisticLockException?

Solution To resolve this error we have two ways: Get the latest object from the database and set the old object values if you need those values to be persisted to the new object and merge it. For the old object set the latest version from Database.

How do I enable optimistic locking in hibernate?

In order to use optimistic locking, we need to have an entity including a property with @Version annotation. While using it, each transaction that reads data holds the value of the version property. Before the transaction wants to make an update, it checks the version property again.

What is optimistic locking and pessimistic locking in hibernate?

There are two models for locking data in a database: Optimistic locking , where a record is locked only when changes are committed to the database. Pessimistic locking , where a record is locked while it is edited.

What is OptimisticLockException?

OptimisticLockException is thrown when an attempt is made to save an entity and it is detected that the database record has been modified since the time the entity being edited was retrieved from the database.


1 Answers

The best way to achieve your goal is to use an interceptor that catches the OptimisticLockingException and allows you to retry the operation.

However, note that this will work only if you get the latest entity snapshot and copy the detached state without the old version property. A strategy like this is prone to lost updates.

Therefore, you should use the retry strategy only if the subset of entity properties you are trying to save can only be updated by your own process, and not by any other concurrent transaction.

To simplify the task, I created the db-util open-source project, which is available on Maven Central as well. It's based on Spring AOP, and it offers a @Retry annotation to mark the services which you want to be retried upon getting an optimistic locking exception.

like image 72
Vlad Mihalcea Avatar answered Sep 23 '22 07:09

Vlad Mihalcea