improve javadoc for LockModes, and deprecate LockOptions.SKIP_LOCKED
Use LockMode.UPGRADE_SKIPLOCKED instead of setting the timeout to -2.
This commit is contained in:
parent
02ad34091c
commit
9d141a2793
|
@ -12,87 +12,136 @@ import jakarta.persistence.LockModeType;
|
|||
|
||||
/**
|
||||
* Instances represent a lock mode for a row of a relational
|
||||
* database table. It is not intended that users spend much
|
||||
* time worrying about locking since Hibernate usually
|
||||
* obtains exactly the right lock level automatically.
|
||||
* Some "advanced" users may wish to explicitly specify lock
|
||||
* levels.
|
||||
* database table. It is not intended that users spend much time
|
||||
* worrying about locking since Hibernate usually obtains exactly
|
||||
* the right lock level automatically. Some "advanced" users may
|
||||
* wish to explicitly specify lock levels.
|
||||
* <p>
|
||||
* This enumeration of lock modes competes with the JPA-defined
|
||||
* {@link LockModeType}, but offers additional options, including
|
||||
* {@link #UPGRADE_NOWAIT} and {@link #UPGRADE_SKIPLOCKED}.
|
||||
*
|
||||
* @author Gavin King
|
||||
*
|
||||
* @see Session#lock(Object, LockMode)
|
||||
* @see LockModeType
|
||||
* @see LockOptions
|
||||
*/
|
||||
public enum LockMode {
|
||||
/**
|
||||
* No lock required. If an object is requested with this
|
||||
* lock mode, a {@link #READ} lock will be obtained if it
|
||||
* is necessary to actually read the state from the database,
|
||||
* No lock required. If an object is requested with this lock
|
||||
* mode, a {@link #READ} lock will be obtained if it turns out
|
||||
* to be necessary to actually read the state from the database,
|
||||
* rather than pull it from a cache.
|
||||
* <p>
|
||||
* This is the "default" lock mode.
|
||||
* This is the "default" lock mode, the mode requested by calling
|
||||
* {@link Session#get(Class, Object)} without passing an explicit
|
||||
* mode. It permits the state of an object to be retrieved from
|
||||
* the cache without the cost of database access.
|
||||
*
|
||||
* @see LockModeType#NONE
|
||||
*/
|
||||
NONE( 0, "none" ),
|
||||
|
||||
/**
|
||||
* A shared lock. Objects in this lock mode were read from
|
||||
* the database in the current transaction, rather than being
|
||||
* pulled from a cache.
|
||||
* A shared lock. Objects in this lock mode were read from the
|
||||
* database in the current transaction, rather than being pulled
|
||||
* from a cache.
|
||||
* <p>
|
||||
* Note that this lock mode is the same as the JPA-defined modes
|
||||
* {@link LockModeType#READ} and {@link LockModeType#OPTIMISTIC}.
|
||||
*
|
||||
* @see LockModeType#OPTIMISTIC
|
||||
*/
|
||||
READ( 5, "read" ),
|
||||
|
||||
/**
|
||||
* Optimistically assume that transaction will not experience
|
||||
* contention for an entity. The version will be verified near
|
||||
* the transaction end.
|
||||
* A shared optimistic lock. Assumes that the current transaction
|
||||
* will not experience contention for the state of an entity. The
|
||||
* version will be checked near the end of the transaction, to
|
||||
* verify that this was indeed the case.
|
||||
* <p>
|
||||
* Note that, despite the similar names this lock mode is not the
|
||||
* same as the JPA-defined mode {@link LockModeType#OPTIMISTIC}.
|
||||
*/
|
||||
OPTIMISTIC( 6, "optimistic" ),
|
||||
|
||||
/**
|
||||
* Optimistically assume that transaction will not experience
|
||||
* contention for an entity. The version will be verified and
|
||||
* incremented near the transaction end.
|
||||
* A kind of exclusive optimistic lock. Assumes that the current
|
||||
* transaction will not experience contention for the state of an
|
||||
* entity. The version will be checked and incremented near the
|
||||
* end of the transaction, to verify that this was indeed the
|
||||
* case, and to signal to concurrent optimistic readers that their
|
||||
* optimistic locks have failed.
|
||||
*
|
||||
* @see LockModeType#OPTIMISTIC_FORCE_INCREMENT
|
||||
*/
|
||||
OPTIMISTIC_FORCE_INCREMENT( 7, "optimistic_force_increment" ),
|
||||
|
||||
/**
|
||||
* A {@code WRITE} lock is obtained when an object is updated
|
||||
* or inserted.
|
||||
* An exclusive write lock. Objects in this lock mode were updated
|
||||
* or inserted in the database in the current transaction.
|
||||
* <p>
|
||||
* This lock mode is for internal use only and is not a valid
|
||||
* argument to {@code load()} or {@code lock()}. These method
|
||||
* throw an exception if {@code WRITE} given as an argument.
|
||||
* This lock mode is for internal use only and is not a legal
|
||||
* argument to {@link Session#get(Class, Object, LockMode)},
|
||||
* {@link Session#refresh(Object, LockMode)}, or
|
||||
* {@link Session#lock(Object, LockMode)}. These methods throw
|
||||
* an exception if {@code WRITE} is given as an argument.
|
||||
* <p>
|
||||
* Note that, despite the similar names, this lock mode is not
|
||||
* the same as the JPA-defined mode {@link LockModeType#WRITE}.
|
||||
*/
|
||||
@Internal
|
||||
WRITE( 10, "write" ),
|
||||
|
||||
/**
|
||||
* Attempt to obtain an upgrade lock, using an Oracle-style
|
||||
* A pessimistic upgrade lock, obtained using an Oracle-style
|
||||
* {@code select for update nowait}. The semantics of this
|
||||
* lock mode, once obtained, are the same as
|
||||
* {@link #PESSIMISTIC_WRITE}.
|
||||
* lock mode, if the lock is successfully obtained, are the same
|
||||
* as {@link #PESSIMISTIC_WRITE}. If the lock is not immediately
|
||||
* available, an exception occurs.
|
||||
*/
|
||||
UPGRADE_NOWAIT( 10, "upgrade-nowait" ),
|
||||
|
||||
/**
|
||||
* Attempt to obtain an upgrade lock, using an Oracle-style
|
||||
* {@code select for update skip locked}. The semantics of
|
||||
* this lock mode, once obtained, are the same as
|
||||
* {@link #PESSIMISTIC_WRITE}.
|
||||
* A pessimistic upgrade lock, obtained using an Oracle-style
|
||||
* {@code select for update skip locked}. The semantics of this
|
||||
* lock mode, if the lock is successfully obtained, are the same
|
||||
* as {@link #PESSIMISTIC_WRITE}. But if the lock is not
|
||||
* immediately available, no exception occurs, but the locked
|
||||
* row is not returned from the database.
|
||||
*/
|
||||
UPGRADE_SKIPLOCKED( 10, "upgrade-skiplocked" ),
|
||||
|
||||
/**
|
||||
* Implemented as {@link #PESSIMISTIC_WRITE}.
|
||||
* A pessimistic shared lock, which prevents concurrent
|
||||
* transactions from writing the locked object. Obtained via
|
||||
* a {@code select for share} statement in dialects where this
|
||||
* syntax is supported, and via {@code select for update} in
|
||||
* other dialects.
|
||||
* <p>
|
||||
* On databases which do not support {@code for share}, this
|
||||
* lock mode is equivalent to {@link #PESSIMISTIC_WRITE}.
|
||||
*
|
||||
* @see LockModeType#PESSIMISTIC_READ
|
||||
*/
|
||||
PESSIMISTIC_READ( 12, "pessimistic_read" ),
|
||||
|
||||
/**
|
||||
* Transaction will obtain a database lock immediately.
|
||||
* A pessimistic upgrade lock, which prevents concurrent
|
||||
* transactions from reading or writing the locked object.
|
||||
* Obtained via a {@code select for update} statement.
|
||||
*
|
||||
* @see LockModeType#PESSIMISTIC_WRITE
|
||||
*/
|
||||
PESSIMISTIC_WRITE( 13, "pessimistic_write" ),
|
||||
|
||||
/**
|
||||
* Transaction will immediately increment the entity version.
|
||||
* A pessimistic write lock which immediately increments
|
||||
* the version of the locked object. Obtained by immediate
|
||||
* execution of an {@code update} statement.
|
||||
*
|
||||
* @see LockModeType#PESSIMISTIC_FORCE_INCREMENT
|
||||
*/
|
||||
PESSIMISTIC_FORCE_INCREMENT( 17, "pessimistic_force_increment" );
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ public class LockOptions implements Serializable {
|
|||
|
||||
/**
|
||||
* Indicates that the database should not wait at all to acquire
|
||||
* a pessimistic lock which is not immediately available.
|
||||
* a pessimistic lock which is not immediately available. This
|
||||
* has the same effect as {@link LockMode#UPGRADE_NOWAIT}.
|
||||
*
|
||||
* @see #getTimeOut
|
||||
*/
|
||||
|
@ -85,7 +86,10 @@ public class LockOptions implements Serializable {
|
|||
* Indicates that rows which are already locked should be skipped.
|
||||
*
|
||||
* @see #getTimeOut()
|
||||
*
|
||||
* @deprecated use {@link LockMode#UPGRADE_SKIPLOCKED}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int SKIP_LOCKED = -2;
|
||||
|
||||
private LockMode lockMode = LockMode.NONE;
|
||||
|
|
|
@ -742,6 +742,9 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
* </ul>
|
||||
* This operation cascades to associated instances if the association is mapped
|
||||
* with {@link jakarta.persistence.CascadeType#REFRESH}.
|
||||
* <p>
|
||||
* This operation requests {@link LockMode#READ}. To obtain a stronger lock,
|
||||
* call {@link #refresh(Object, LockMode)}.
|
||||
*
|
||||
* @param object a persistent or detached instance
|
||||
*/
|
||||
|
@ -844,9 +847,24 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
/**
|
||||
* Return the persistent instance of the given entity class with the given identifier,
|
||||
* or null if there is no such persistent instance. If the instance is already associated
|
||||
* with the session, return that instance. This method never returns an uninitialized instance.
|
||||
* with the session, return that instance. This method never returns an uninitialized
|
||||
* instance.
|
||||
* <p>
|
||||
* This operation is very similar to {@link #find(Class, Object)}.
|
||||
* <p>
|
||||
* This operation requests {@link LockMode#NONE}, that is, no lock, allowing the object
|
||||
* to be retrieved from the cache without the cost of database access. However, if it is
|
||||
* necessary to read the state from the database, the object will be returned with the
|
||||
* lock mode {@link LockMode#READ}.
|
||||
* <p>
|
||||
* To bypass the second-level cache, and ensure that the state is read from the database,
|
||||
* either:
|
||||
* <ul>
|
||||
* <li>call {@link #get(Class, Object, LockMode)} with the explicit lock mode
|
||||
* {@link LockMode#READ}, or
|
||||
* <li>{@linkplain #setCacheMode(CacheMode) set the cache mode} to {@link CacheMode#IGNORE}
|
||||
* before calling this method.
|
||||
* </ul>
|
||||
*
|
||||
* @param entityType the entity type
|
||||
* @param id an identifier
|
||||
|
@ -858,8 +876,8 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
/**
|
||||
* Return the persistent instance of the given entity class with the given identifier,
|
||||
* or null if there is no such persistent instance. If the instance is already associated
|
||||
* with the session, return that instance. This method never returns an uninitialized instance.
|
||||
* Obtain the specified lock mode if the instance exists.
|
||||
* with the session, return that instance. This method never returns an uninitialized
|
||||
* instance. Obtain the specified lock mode if the instance exists.
|
||||
* <p>
|
||||
* Convenient form of {@link #get(Class, Object, LockOptions)}.
|
||||
* <p>
|
||||
|
@ -878,8 +896,8 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
/**
|
||||
* Return the persistent instance of the given entity class with the given identifier,
|
||||
* or null if there is no such persistent instance. If the instance is already associated
|
||||
* with the session, return that instance. This method never returns an uninitialized instance.
|
||||
* Obtain the specified lock mode if the instance exists.
|
||||
* with the session, return that instance. This method never returns an uninitialized
|
||||
* instance. Obtain the specified lock mode if the instance exists.
|
||||
*
|
||||
* @param entityType the entity type
|
||||
* @param id an identifier
|
||||
|
@ -892,7 +910,8 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
/**
|
||||
* Return the persistent instance of the given named entity with the given identifier,
|
||||
* or null if there is no such persistent instance. If the instance is already associated
|
||||
* with the session, return that instance. This method never returns an uninitialized instance.
|
||||
* with the session, return that instance. This method never returns an uninitialized
|
||||
* instance.
|
||||
*
|
||||
* @param entityName the entity name
|
||||
* @param id an identifier
|
||||
|
@ -903,9 +922,9 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
|
||||
/**
|
||||
* Return the persistent instance of the given entity class with the given identifier,
|
||||
* or null if there is no such persistent instance. (If the instance is already associated
|
||||
* with the session, return that instance. This method never returns an uninitialized instance.)
|
||||
* Obtain the specified lock mode if the instance exists.
|
||||
* or null if there is no such persistent instance. If the instance is already associated
|
||||
* with the session, return that instance. This method never returns an uninitialized
|
||||
* instance. Obtain the specified lock mode if the instance exists.
|
||||
* <p/>
|
||||
* Convenient form of {@link #get(String, Object, LockOptions)}
|
||||
*
|
||||
|
@ -922,8 +941,8 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
/**
|
||||
* Return the persistent instance of the given entity class with the given identifier,
|
||||
* or null if there is no such persistent instance. If the instance is already associated
|
||||
* with the session, return that instance. This method never returns an uninitialized instance.
|
||||
* Obtain the specified lock mode if the instance exists.
|
||||
* with the session, return that instance. This method never returns an uninitialized
|
||||
* instance. Obtain the specified lock mode if the instance exists.
|
||||
*
|
||||
* @param entityName the entity name
|
||||
* @param id an identifier
|
||||
|
@ -1235,7 +1254,8 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
/**
|
||||
* A timeout value indicating that the database should not
|
||||
* wait at all to acquire a pessimistic lock which is not
|
||||
* immediately available.
|
||||
* immediately available. This has the same effect as
|
||||
* {@link LockMode#UPGRADE_NOWAIT}.
|
||||
*/
|
||||
int PESSIMISTIC_NO_WAIT = LockOptions.NO_WAIT;
|
||||
|
||||
|
|
|
@ -1874,10 +1874,10 @@ public abstract class Dialect implements ConversionContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the {@code FOR UPDATE OF column_list} fragment appropriate for this
|
||||
* dialect given the aliases of the columns to be write locked.
|
||||
* Get the {@code FOR UPDATE OF} or {@code FOR SHARE OF} fragment appropriate
|
||||
* for this dialect given the aliases of the columns to be locked.
|
||||
*
|
||||
* @param aliases The columns to be write locked.
|
||||
* @param aliases The columns to be locked.
|
||||
* @param lockOptions the lock options to apply
|
||||
* @return The appropriate {@code FOR UPDATE OF column_list} clause string.
|
||||
*/
|
||||
|
|
|
@ -691,9 +691,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String getForUpdateString(String aliases, LockOptions lockOptions) {
|
||||
/*
|
||||
* Parent's implementation for (aliases, lockOptions) ignores aliases.
|
||||
*/
|
||||
// parent's implementation for (aliases, lockOptions) ignores aliases
|
||||
if ( aliases.isEmpty() ) {
|
||||
LockMode lockMode = lockOptions.getLockMode();
|
||||
for ( Map.Entry<String, LockMode> entry : lockOptions.getAliasSpecificLocks() ) {
|
||||
|
|
|
@ -19,7 +19,7 @@ public class RefreshEvent extends AbstractEvent {
|
|||
private final Object object;
|
||||
private String entityName;
|
||||
|
||||
private LockOptions lockOptions = new LockOptions().setLockMode(LockMode.READ);
|
||||
private LockOptions lockOptions = new LockOptions(LockMode.READ);
|
||||
|
||||
public RefreshEvent(Object object, EventSource source) {
|
||||
super(source);
|
||||
|
|
|
@ -43,7 +43,7 @@ public class SimpleSelect {
|
|||
|
||||
protected LockOptions lockOptions = new LockOptions( LockMode.READ );
|
||||
|
||||
private Dialect dialect;
|
||||
private final Dialect dialect;
|
||||
|
||||
|
||||
public SimpleSelect addColumns(String[] columnNames, String[] columnAliases) {
|
||||
|
@ -189,7 +189,7 @@ public class SimpleSelect {
|
|||
}
|
||||
|
||||
if ( lockOptions != null ) {
|
||||
buf = new StringBuilder(dialect.applyLocksToSql( buf.toString(), lockOptions, null ) );
|
||||
buf = new StringBuilder( dialect.applyLocksToSql( buf.toString(), lockOptions, null ) );
|
||||
}
|
||||
|
||||
return dialect.transformSelectString( buf.toString() );
|
||||
|
|
Loading…
Reference in New Issue