[hibernate-dev] JPA2 locking

Scott Marlow smarlow at redhat.com
Tue Oct 20 11:16:08 EDT 2009

On 10/20/2009 10:12 AM, Emmanuel Bernard wrote:
> On 20 oct. 09, at 15:45, Scott Marlow wrote:
>> On 10/16/2009 03:40 PM, Emmanuel Bernard wrote:
>>> When I discussed that with Gavin, I believe this idea is that you can
>>> implement the optimistic locking in the following way:
>>> - when locking an object read the version number (or if already
>>> loaded keep this one - not sure about that detail)
>>> - when flushing or right before commit, read the version number again
>>> from the database and compare.
>>> If they are different => exception
>>> A provider may but is not forced to acquire the lock
>>> Note that today we implement Optimistic in a pessimistic way (ie que
>>> acquire the DB lock right away).
>>> So there are three levels really
>>> no lock => we check versions upon UPDATE operations
>>> optimistic => we check versions on reads as well and verify consistency
>>> pessimistic => we lock at the DB level.
>> Currently, the Hibernate EM depends on Hibernate core for locking (as it
>> should).  I have a few questions about how achieve the above locking
>> with Hibernate core and about what changes are needed.
>> The JPA 2 locking operations that we need support for are:
>> OPTIMISTIC (equal to READ) - should read the version initially and
>> confirm that it hasn't changed at transaction commit time.  We should
>> throw OptimisticLockException if the version has changed.  I think that
>> we need a new LockMode for this (similar to LockMode.READ).
> correct.
>>  For
>> extended persistence context (meaning that the duration is beyond the
>> end of transaction), I think that we use the entity value from the
>> extended persistence context as is but should still confirm that it
>> hasn't changed at commit time (optimistically assume that it hasn't
>> changed initially).
> I am not sure where you are getting at, I don't see the difference 
> between the extended PC and the classical PC in this case.

I assume that if entity is already read in a previous transaction, we 
could validate the version at transaction commit time (throwing an 
exception if it is stale).  I agree that this is logically the same as 
the classical PC case.  I just wanted to point out that we are not 
validating more than once during the transaction.

>> OPTIMISTIC_FORCE_INCREMENT (equal to WRITE) - should read the version
>> initially.  At transaction commit time, confirm that the version hasn't
>> changed as we increment it via update.  We should throw
>> OptimisticLockException if the version has changed.  I think that we
>> need a new LockMode for this (similar to LockMode.READ and
>> LockMode.FORCE).  Same rules as above for extended persistence context.
> yes same logic as above.
>> PESSIMISTIC_WRITE - Should obtain a database write lock on the entity.
>> Hibernate LockMode.Upgrade could be used for this on dialects that
>> support it.  For dialects that don't support LockMode.Upgrade, a
>> PessimisticLockException should be thrown.
>> PESSIMISTIC_READ - Should obtain a shared database read lock on the
>> entity (for the duration of the database transaction).  How should we
>> support this?  The JPA 2 specification allows the PESSIMISTIC_WRITE
>> behavior to be used.
> Ideally we should use:
>  - nothing but reading if we are in repeatable read

Okay, we can check the isolation level.

>  - a shared lock on databases that do support the contract

We need new LockMode support for getting the shared lock (and indication 
if contract is supported).

>  - fall back to P_WRITE if it does not.

Sounds good.

>> increment version at transaction commit time (even if entity isn't
>> updated).  I think that we need a new LockMode for this.  We need a way
>> to throw an exception if not supported.
> No it is the same as PESS_WRITE but with a version increment because 
> the spec describes possible escalations as P_R < P_W < P_FI
> So I think it's mappable to LockMode.FORCE

Nice!  I assume that LockMode.FORCE is always supported since we can do 
the increment immediately to get the write lock.

>> For pessimistic locks, only lock element collections and relationships
>> owned by the entity, if property javax.persistence.lock.scope is set to
>> "PessimisticLockScope.EXTENDED".
>> Assuming we do the above, we need to release note that READ/WRITE locks
>> are obtained in optimistic manner which is a change from our JPA 1 
>> support.
> I don't understand.

In our JPA 1 support, LockModeType of READ is implemented with 
LockMode.UPGRADE (pessimistic lock is obtained).  With the above 
proposal, this would change in our JPA 2 implementation to use an 
optimistic lock (just read version at load time and validate that 
version didn't change at commit time).

In our JPA 1 support, LockModeType of WRITE is implemented with 
LockMode.FORCE (pessimistic lock is obtained with version incremented).  
With the above proposal, this would change in our JPA 2 implementation 
to use same as OPTIMISTIC_FORCE_INCREMENT above.

>> Comments?
>> Any volunteers willing to help with JPA 2 implementation (coding,
>> testing, moral support) are welcome to join in.:-)
>> Scott
>> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev

More information about the hibernate-dev mailing list