Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate LockModes/LockOptions

Tags:

java

hibernate

I am going through Hibernate Documentation an came across the LockModes. Are these same as Isolation levels that we use for database? How are they different from Isolation levels?

I am trying a simple example and observed that the hibernate is hitting the database when I use session.load() method itself instead of hitting the DB when I call some methods on the loaded object.

session.beginTransaction(); //Line 1
DomesticCat d1 = (DomesticCat)session.load(DomesticCat.class, 1L,LockOptions.UPGRADE); //Line 2
d1.meow(); //Line 3
session.getTransaction().commit(); //Line 4

I observed that hibernate hits the database at line 2 itself, please tell me why it happens like that? If I remove the LockOptions parameter then the DB hit is made on Line 3 instead of Line 2

The API for LockOptions gives very little details on what they are:

READ represents LockMode.READ (timeout + scope do not apply)

What does it mean that timeout + scope do not apply?

UPGRADE represents LockMode.UPGRADE (will wait forever for lock and scope of false meaning only entity is locked)

When we should use UPGRADE? what it means that scope of false meaning only entity is locked?

May be these are basic questions for experienced guys, please help me in understanding the concept here.

Thanks for looking my post.

like image 912
Chaitanya Avatar asked Jan 09 '14 20:01

Chaitanya


1 Answers

Isolation Levels affect what you see.

Lock Modes affect what you are allowed to do.

The normal settings for hibernate are read-committed isolation and optimistic locks.

With optimistic locking, when two people try to edit the same data at the same time, the second one to commit will get an exception.

  1. User 1 loads DomesticCat#1066 without upgrade lock.
  2. User 2 loads DomesticCat#1066 without upgrade lock.
  3. User 2 changes cat's name and commits.
  4. User 1 changes cat's birthday, attempts to commit, an exception is thrown.

If pessimistic locks are in use, by selecting LockMode UPGRADE, then nobody else will be allowed to alter the data until the person who asked for the Lock UPGRADE releases it.

  1. User 1 loads DomesticCat#1066 with upgrade lock.
  2. User 2 loads DomesticCat#1066 without upgrade lock.
  3. User 2 changes cat's name and attempts to commit. This operation is not allowed until User 1 releases the lock, so the database blocks and User 2's session sits and waits.
  4. User 1 changes cat's birthday, commits.
  5. User 2's update can now try to commit, but since they used optimistic locking now they will be the one who sees an exception.

The reason the query has to be executed as soon as you load when you upgrade is that it's implemented using the select ... for update statement and hibernate promises you that you'll have the lock when that method returns, so it has to execute the statement right away. When you don't need to hold the lock, hibernate can be lazy and defer loading the data until you show that you actually do need it.

Generally you upgrade the lock level when you have an operation that must complete regardless of what other people are doing. For example, when it's users, you can just show them the error and they can adjust their work and try again. But if the updates are being made by a messaging server or background process, handling exceptions and trying again can be very complicated, so it might be better to just lock the record so you can be sure your update goes in.

like image 68
Affe Avatar answered Oct 12 '22 14:10

Affe