Show Table of Contents
11.5. Pessimistic Locking
11.5.1. About Pessimistic Locking
It is not intended that users spend much time worrying about locking strategies. It is usually enough to specify an isolation level for the JDBC connections and then simply let the database do all the work. However, advanced users may wish to obtain exclusive pessimistic locks or re-obtain locks at the start of a new transaction.
Hibernate will always use the locking mechanism of the database; it never lock objects in memory.
LockModeclass defines the different lock levels that can be acquired by Hibernate. A lock is obtained by the following mechanisms:
LockMode.WRITEis acquired automatically when Hibernate updates or inserts a row.
LockMode.UPGRADEcan be acquired upon explicit user request using
SELECT ... FOR UPDATEon databases which support that syntax.
LockMode.UPGRADE_NOWAITcan be acquired upon explicit user request using a
SELECT ... FOR UPDATE NOWAITunder Oracle.
LockMode.READis acquired automatically when Hibernate reads data under Repeatable Read or Serializable isolation level. It can be re-acquired by explicit user request.
LockMode.NONErepresents the absence of a lock. All objects switch to this lock mode at the end of a
Transaction. Objects associated with the session via a call to
saveOrUpdate()also start out in this lock mode.
The "explicit user request" is expressed in one of the following ways:
- A call to
Session.load(), specifying a
- A call to
- A call to
Session.load()is called with
UPGRADE_NOWAIT, and the requested object was not yet loaded by the session, the object is loaded using
SELECT ... FOR UPDATE. If
load()is called for an object that is already loaded with a less restrictive lock than the one requested, Hibernate calls
lock()for that object.
Session.lock()performs a version number check if the specified lock mode is
UPGRADE_NOWAIT. In the case of
SELECT ... FOR UPDATEis used.
If the requested lock mode is not supported by the database, Hibernate uses an appropriate alternate mode instead of throwing an exception. This ensures that applications are portable.
11.5.2. Connection Release Modes
One of the legacies of Hibernate 2.x JDBC connection management meant that a
Sessionwould obtain a connection when it was first required and then maintain that connection until the session was closed. Hibernate 3.x introduced the notion of connection release modes that would instruct a session how to handle its JDBC connections. The following discussion is pertinent only to connections provided through a configured
ConnectionProvider. User-supplied connections are outside the breadth of this discussion. The different release modes are identified by the enumerated values of
ON_CLOSE: is the legacy behavior described above. The Hibernate session obtains a connection when it first needs to perform some JDBC access and maintains that connection until the session is closed.
AFTER_TRANSACTION: releases connections after a
org.hibernate.Transactionhas been completed.
AFTER_STATEMENT(also referred to as aggressive release): releases connections after every statement execution. This aggressive releasing is skipped if that statement leaves open resources associated with the given session. Currently the only situation where this occurs is through the use of
The configuration parameter
hibernate.connection.release_modeis used to specify which release mode to use. The possible values are as follows:
auto(the default): this choice delegates to the release mode returned by the
org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode()method. For JTATransactionFactory, this returns ConnectionReleaseMode.AFTER_STATEMENT; for JDBCTransactionFactory, this returns ConnectionReleaseMode.AFTER_TRANSACTION. Do not change this default behavior as failures due to the value of this setting tend to indicate bugs and/or invalid assumptions in user code.
on_close: uses ConnectionReleaseMode.ON_CLOSE. This setting is left for backwards compatibility, but its use is discouraged.
after_transaction: uses ConnectionReleaseMode.AFTER_TRANSACTION. This setting should not be used in JTA environments. Also note that with ConnectionReleaseMode.AFTER_TRANSACTION, if a session is considered to be in auto-commit mode, connections will be released as if the release mode were AFTER_STATEMENT.
after_statement: uses ConnectionReleaseMode.AFTER_STATEMENT. Additionally, the configured
ConnectionProvideris consulted to see if it supports this setting (
supportsAggressiveRelease()). If not, the release mode is reset to ConnectionReleaseMode.AFTER_TRANSACTION. This setting is only safe in environments where we can either re-acquire the same underlying JDBC connection each time you make a call into
ConnectionProvider.getConnection()or in auto-commit environments where it does not matter if we re-establish the same connection.