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). 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).
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.
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.
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.
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.
Comments?
Any volunteers willing to help with JPA 2 implementation (coding,
testing, moral support) are welcome to join in. :-)
Scott