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 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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With