persistence@glassfish.java.net

RE: pessimistic locking

From: Scott Oaks <Scott.Oaks_at_Sun.COM>
Date: Mon, 12 Feb 2007 15:59:10 -0500

Hi Gordon --

> Given the particularly arbitrary nature of this method combination we will
> want to go a different route. Given the available APIs the best way to support
> pessimistic locking on the lock API is to have configurable class level
> pessimistic locks. For example the fastest feature to develop would be to add
> a persistence.xml property that would cause any lock obtained on a particular
> class to be a pessimistic lock.

I think that sounds fine. The reason why SPEC wants to use that sequence
specifically is that the getReference() call needn't go to the database;
it can create a shadow reference. If an em.find() call were used and the
data wasn't in the cache, then the em.find() call will go to the
database once to get the data, and then the lock() call will have to go
do the database to lock the row (and reload all the data, which may have
changed in the interim). getReference could avoid multiple DB calls.

But I think in our case, we go to the database on getReference() anyway
if the row isn't in the cache. As long as you don't see an issue in the
row locking happening after the getReference call (that is, as long as
we maintaing the Repeatble read semantics of the lock), it's fine.
Though if there is a way to avoid the multiple DB calls, so much the
better.

> The feature would be relatively quick to implement but given the status
> of the 9.1 branch (feature complete?) may have to wait until an update.

I can always work on getting a waiver. Can you give me a really rough,
top-of-the-head estimate of the time involved in "relatively quick"?

> Using this particular combination could be a SpecJ only feature but
> customers would be better served by a practical feature.

I agree, but I think this is a good solution until it's addressed in the
JPA spec. Customers can't necessarily wait until the spec addresses
pessimistic locking, and the other option available now (use a query and
set hints) is quite impractical. Configuring locking in the
persistence.xml is, I think, a good compromise.

-Scott

> --Gordon
>
>
> -----Original Message-----
> From: Scott.Oaks_at_Sun.COM [mailto:Scott.Oaks_at_Sun.COM]On Behalf Of Scott
> Oaks
> Sent: Monday, February 12, 2007 2:46 PM
> To: persistence_at_glassfish.dev.java.net
> Subject: pessimistic locking
>
>
> The SPEC organization is in the process of developing a JPA-based
> benchmark based on the CMP 2.1 implementation of SPECjAppServer 2004.
> Certain objects used in that benchmark are concurrently modified by
> multiple clients simultaneously; in order to score well on the
> benchmark, pessimistic locking must be used on those entities.
> Otherwise, the time spent rolling back and retrying the operation (often
> multiple times) is quite excessive.
>
> Realizing that pessimistic locking in the JPA spec is non-portable, SPEC
> intends to go this route: the highly-contended objects will be obtained
> this way:
>
> Customer c = em.getReference(Customer.class, 1);
> em.lock(c, LockModeType.WRITE);
>
> And have the appserver vendor configure (though deployment descriptors
> or something else that doesn't modify the code) the locks obtained that
> way to be pessimistic locks. They have checked several JPA
> implementations, all of whom say that they will be able to support such
> a feature (including, apparently, Toplink, though AFAIK, that doesn't
> apply to the subset of toplink in glassfish).
>
> This is a feature we would need quite soon; preferably in 9.1 or at
> least in an update soon after. What is the feasibility of doing so?
>
> -Scott