[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.
>
>>
>> PESSIMISTIC_FORCE_INCREMENT - Same as PESSIMISTIC_READ but with an
>> 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