Search code examples
javaspringhibernatejpatransactions

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


Solution

  • 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.