Database locking can apply to any database applications.
There are two common strategies when dealing with updates to database
records, pessimistic locking and optimistic locking.
"Optimistic locking" is more scalable than pessimistic locking when dealing with a
highly concurrent environment. However pessimistic locking is a better solution for situations
where the possibility of simultaneous updates to the same data by multiple sources
(for example, different applications use same database to update) is common, hence making the possibility of "data clobbering" , a
likely scenario. Lets look at a brief explanation of each of these two locking strategies.
Pessimistic locking is when you want to reserve a record for exclusive update by
locking the database record(entire table). Hibernate supports pessimistic locking
(using the underlying database, not in-memory) via one of the following methods:
1. Session.get
2. Session.load
3. Session.lock
4. Session.refresh
5. Query.setLockMode
Although each of the methods accepts different params, the one common parameter
across all is the LockMode class, which provides various locking modes such as NONE,
READ, UPGRADE, UPGRADE_NOWAIT, and WRITE.
For example, to obtain a Timesheet record for updating,
we could use the following code: (assume database supports locking system):
public Timesheet getTimesheetWithLock(int timesheetId)
{
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Timesheet timesheet = (Timesheet)session.get(Timesheet.class,
new Integer(timesheetId), LockMode.UPGRADE);
session.getTransaction().commit();
session.close();
return timesheet;
}
Optimistic locking means that you will not lock a given database record or table and
instead check a property of some sort (for example, a timestamp column) to
ensure the data has not changed since you read it. Hibernate supports this using a
version property, which can either be checked manually by the application or automatically
by Hibernate for a given session. For example, the following code excerpt is taken
verbatim out of the Hibernate reference documentation and shows how an application
can manually compare the oldVersion with the current version using a getter method
(for example):
// foo is an instance loaded by a previous Session
session = factory.openSession();
int oldVersion = foo.getVersion();
session.load( foo, foo.getKey() );
if ( oldVersion!=foo.getVersion )
throw new StaleObjectStateException();
foo.setProperty(“bar”);
session.flush();
session.connection().commit();
session.close();
StaleObjectStateException, is an exception in the org.hibernate package.