Java Reference
In-Depth Information
with the changes made to objects, before committing the transaction. If Hiber-
nate determines that a row has been updated by another transaction, it throws a
StaleObjectStateException
, which is mapped by Spring's
HibernateTemplate
to
OptimisticLockingFailureException
. An application must handle this exception
by first rolling back the transaction and closing the
Session
. It can then open a
new
Session
and retry the transaction.
Hibernate's optimistic locking mechanism works quite well. Because it is a
declarative mechanism, Hibernate ensures that it is used consistently for all data-
base accesses.
Using pessimistic locking
Hibernate provides a programmatic mechanism for pessimistic locking. An appli-
cation can lock an object when loading it, and lock objects when executing a
query. It can also lock a previously loaded object. An application locks the table
rows corresponding to objects by specifying a lock mode when calling the follow-
ing Hibernate methods:
Session.load()
,
Session.lock()
, and
Query.setLock-
Mode()
. There are several kinds of lock mode, but the values that support
pessimistic locking are
LockMode.UPGRADE
and
LockMode.UPGRADE_NO_WAIT
.
The
Session.load()
method, which loads an object, has an optional
lockMode
parameter, which specifies whether to lock the object. When one of these values is
specified,
load()
behaves as follows: If the specified object is not loaded,
load()
uses
SELECT FOR UPDATE
[NO WAIT]
to retrieve the object. If the object is already
loaded with a less restrictive lock,
load()
calls
Session.lock()
.
The method
Session.lock()
is used to lock an already loaded object. When
the lock mode is either
UPGRADE
or
UPGRADE_NO_WAIT
,
lock()
does a version check
using
SELECT
FOR
UPDATE
[NO WAIT]
and throws a
StaleObjectStateException
if
the object is out of date.
The
Query.setLockMode()
method is used to specify whether a query should
lock the objects it retrieves. If the application specifies a
lockMode
of either
UPGRADE
or
UPGRADE_NO_WAIT
, Hibernate uses a
SELECT FOR UPDATE [NO WAIT]
query to lock the objects.
Here is how the
HibernateOrderRepositoryImpl
can use pessimistic locking:
public class HibernateOrderRepositoryImpl
…
public List findOrdersToSend () {
return getHibernateTemplate().executeFind(
new HibernateCallback() {
public Object doInHibernate(Session session)
Search WWH ::
Custom Search