Concurrent updates handling in hibernate Concurrent updates handling in hibernate spring spring

Concurrent updates handling in hibernate


Can somebody explain me if we use spring for the transaction management, how concurrent updates will be handled by hibernate (In memory automatic version management of hibernate) or I have to put version column in the database to take care of concurrent updates manually.

Whether you're using Spring for transaction management or not doesn't really matter and isn't relevant when it comes to concurrency management, this is actually handled by Hibernate. Hibernate can use 2 strategies to handle concurrent updates: optimistic locking and pessimistic locking.

Optimistic

When using optimistic locking, you map a special attribute (a number, a timestamp) as a version (so you actually have a column for it). This version is read when you retrieve an entity and included in the where clause during an update and incremented by Hibernate.

To illustrate how this works, let's imagine you load a Person entity by id=1 and with a current version=1. After a save, Hibernate will perform something like this:

update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;

So, now, imagine you have two concurrent transactions running, each of them loading the same entity (same version number) and changing the name.

Let's say transaction #1 is committed first, the following query is performed:

update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;

It succeeds and the version gets incremented.

Then transaction #2 is committed, the following query is performed:

update PERSON set ID=1, NAME='NAME 2', VERSION=2 where ID=1 and VERSION=1;

This one won't update anything because the where clause won't match any record. This is where you'll get an optimistic concurrency exception.

This strategy is appropriate when you don't maintain the connection, when concurrent accesses are not frequent, and scales really well. And everything is of course handled transparently by Hibernate for you, as long as you map a version attribute.

Pessimistic

When using pessimistic locking, Hibernate locks a record for your exclusive use until you have finished with it (typically using a SELECT ... FOR UPDATE). Any other concurrent transaction trying to access the same record will get suspended until the lock is removed. This strategy gives better predictability, at the price of performance and doesn't scale indefinitely.

References


There are JPA implementations like objectDB in which optimistic locking is activated by default and user don't need to maintain version variable in database table as, it is internally taken care by objectDB. Optimistic locking is good where updates are not frequent and where locking have implicit costs like in e-commerce where locking means loss of business. Pessimistic locking is ideal where concurrency is not much demanded and transaction is finished quickly to free up the resource.


There is some documentation about sessions and transactions on the Hibernate community wiki. It's ultimately handled by the underlying RDBMS transactions, but you need to pay attention to the life cycle of the objects loaded or saved.