Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Isolation Level vs Optimistic Locking-Hibernate , JPA

I have a web application where I want to ensure concurrency with a DB level lock on the object I am trying to update. I want to make sure that a batch change or another user or process may not end up introducing inconsistency in the DB.

I see that Isolation levels ensure read consistency and optimistic lock with @Version field can ensure data is written with a consistent state.

My question is can't we ensure consistency with isolation level only? By making my any transaction that updates the record Serializable(not considering performance), will I not ensure that a proper lock is taken by the transaction and any other transaction trying to update or acquire lock or this transaction will fail? Do I really need version or timestamp management for this?

like image 360
Dhruv Avatar asked Jan 19 '17 20:01

Dhruv


People also ask

Does hibernate use optimistic locking?

Optimist lock in hibernate checks VERSION of ROW. If Alice product has the same version as she fetched it will save to db. If alice wanted to save product but version is not the same as she fetched will throw exception.

What is optimistic locking JPA?

Understanding Optimistic Locking 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. If the value has changed in the meantime, an OptimisticLockException is thrown.

Should I use optimistic locking?

Optimistic locking is used when you don't expect many collisions. It costs less to do a normal operation but if the collision DOES occur you would pay a higher price to resolve it as the transaction is aborted. Pessimistic locking is used when a collision is anticipated.

When would you use optimistic over pessimistic locking?

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.


2 Answers

Depending on isolation level you've chosen, specific resource is going to be locked until given transaction commits or rollback - it can be lock on a whole table, row or block of sql. It's a pessimistic locking and it's ensured on database level when running a transaction.

Optimistic locking on the other hand assumes that multiple transactions rarely interfere with each other so no locks are required in this approach. It is a application-side check that uses @Version attribute in order to establish whether version of a record has changed between fetching and attempting to update it.

It is reasonable to use optimistic locking approach in web applications as most of operations span through multiple HTTP request. Usually you fetch some information from database in one request, and update it in another. It would be very expensive and unwise to keep transactions open with lock on database resources that long. That's why we assume that nobody is going to use set of data we're working on - it's cheaper. If the assumption happens to be wrong and version has changed in between requests by someone else, Hibernate won't update the row and will throw OptimisticLockingException. As a developer, you are responsible for managing this situation.

Simple example. Online auctions service - you're watching an item page. You read its description and specification. All of it takes, let's say, 5 minutes. With pessimistic locking and some isolation levels you'd block other users from this particular item page (or all of the items even!). With optimistic locking everybody can access it. After reading about the item you're willing to bid on it so you click the proper button. If any other of users watching this item and change its state (owner changed its description, someone other bid on it) in the meantime you will probably (depending on app implementation) be informed about the changes before application will accept your bid because version you've got is not the same as version persisted in database.

Hope that clarifies a few things for you.

like image 51
Piotr Podraza Avatar answered Sep 27 '22 16:09

Piotr Podraza


Unless we are talking about some small, isolated web application (only app that is working on a database), then making all of your transactions to be Serializable would mean having a lot of confidence in your design, not taking into account the fact that it may not be the only application hitting on that certain database.

In my opinion the incorporation of Serializable isolation level, or a Pessimistic Lock in other words, should be very well though decision and applied for:

  • Large databases and short transactions that update only a few rows
  • Where the chance that two concurrent transactions will modify the same rows is relatively low.
  • Where relatively long-running transactions are primarily read-only.

Based on my experience, in most of the cases using just the Optimistic Locking would be the most beneficial decision, as frequent concurrent modifications mostly happen in only small percentage of cases. Optimistic locking definately also helps other applications run faster (dont think only of yourself!).

So when we take the Pessimistic - Optimistic locking strategies spectrum, in my opinion the truth lies somewhere more towards the Optimistic locking with a flavor of serializable here and there.

I really cannot reference anything here as the answer is based on my personal experience with many complex web projects and from my notes when i was preapring to my JPA Certificate.

Hope that helps.

like image 37
Maciej Kowalski Avatar answered Sep 27 '22 15:09

Maciej Kowalski