I want to increment a field in a database table by 1 using Hibernate.
I can do this by simply loading an object, incrementing the value and updating the object however if another thread comes along and updates the field in between the load and the update then the value will become corrupted.
So instead I have called an update directly on the database:
Query updateHits = createQuery(
"UPDATE Job SET hitCount = hitCount + 1 WHERE id = :jobId" );
updateHits.setInteger( "jobId", job.getId() );
updateHits.executeUpdate();
However my understanding is that this bypasses optimistic locking in the database and I am currently experiencing an issue with deadlocks in SQL server and I believe this is the culprit.
Is there a way to increment a field without calling the update directly and while maintaining data integrity?
I can do this by simply loading an object, incrementing the value and updating the object however if another thread comes along and updates the field in between the load and the update then the value will become corrupted.
If the second thread is also using hibernate and you're using hibernate versioning (@Version) the one thread that commits first and changes the object will set the new version on the object.
When the second thread commit comes in, hibernate will check for optimistic lock fail and will throw an exception - StaleObjectException if I'm not mistaken. Will a catch block around your concurrent code you'll have the chance to load the object again and try your update if it makes sense. If you're using JPA an OptimisticLockException will be thrown.
There are loads of info at the Hibernate Optimistic Concurrency Control Section.
Cheers!
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