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@lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/hibernate-dev > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev