[hibernate-dev] JPA2 locking

Steve Ebersole steve at hibernate.org
Tue Oct 20 11:46:30 EDT 2009


Just wanted to point out that "checking" the isolation level may not be
accurate.  HSQLDB, for example, lets you set any isolation you want and
dutifully reports it back even though it (used to, at least) only
supports READ UNCOMMITTED.  But, I personally think we need to just
assume that we are running in at least READ COMMITTED (HSQLDB in a
single user environment would behave as if READ COMMITTED).  READ
UNCOMMITTED has to be universally considered evil in real practice :)

WRT PESSIMISTIC_READ, it really comes down to the intent.  Is this
supposed to stop other writers from writing to the given data until we
are done with it?  Aka, would this be an intention lock (I intend to
update this data so don't let other writers in here right now)?  Or
merely a guarantee of repeatable read?

On Tue, 2009-10-20 at 11:16 -0400, Scott Marlow wrote:
> 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
> >
> 
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
-- 
Steve Ebersole <steve at hibernate.org>
Hibernate.org




More information about the hibernate-dev mailing list