Skip to content

Commit

Permalink
add LockOption and overload EM.lock()
Browse files Browse the repository at this point in the history
see #399
  • Loading branch information
gavinking committed Aug 11, 2023
1 parent 74798b7 commit 4e8db0f
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 2 deletions.
48 changes: 48 additions & 0 deletions api/src/main/java/jakarta/persistence/EntityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,54 @@ public <T> T getReference(Class<T> entityClass,
public void lock(Object entity, LockModeType lockMode,
Map<String, Object> properties);

/**
* Lock an entity instance that is contained in the persistence
* context with the specified lock mode type, using specified
* {@linkplain LockOption options}.
* <p>If a pessimistic lock mode type is specified and the entity
* contains a version attribute, the persistence provider must
* also perform optimistic version checks when obtaining the
* database lock. If these checks fail, the
* <code>OptimisticLockException</code> will be thrown.
* <p>If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* <ul>
* <li> the <code>PessimisticLockException</code> will be thrown
* if the database locking failure causes transaction-level
* rollback
* <li> the <code>LockTimeoutException</code> will be thrown if
* the database locking failure causes only statement-level
* rollback
* </ul>
* <p>If a vendor-specific {@link LockOption} is not recognized,
* it is silently ignored.
* <p>Portable applications should not rely on the standard
* {@linkplain Timeout timeout option}. Depending on the database
* in use and the locking mechanisms used by the provider, the
* option may or may not be observed.
* @param entity entity instance
* @param lockMode lock mode
* @param options standard and vendor-specific options
* @throws IllegalArgumentException if the instance is not an
* entity or is a detached entity
* @throws TransactionRequiredException if there is no
* transaction or if invoked on an entity manager which
* has not been joined to the current transaction
* @throws EntityNotFoundException if the entity does not exist
* in the database when pessimistic locking is
* performed
* @throws OptimisticLockException if the optimistic version
* check fails
* @throws PessimisticLockException if pessimistic locking fails
* and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call is made
* @since 3.2
*/
public void lock(Object entity, LockModeType lockMode,
LockOption... options);

/**
* Refresh the state of the instance from the database,
* overwriting changes made to the entity, if any.
Expand Down
36 changes: 36 additions & 0 deletions api/src/main/java/jakarta/persistence/LockOption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Gavin King - 3.2


package jakarta.persistence;

/**
* An option influencing the behavior of {@link EntityManager#lock}.
* Built-in options control {@linkplain PessimisticLockScope scope},
* and {@linkplain Timeout timeouts}.
*
* <p>This interface may be implemented by custom provider-specific
* options which extend the options defined by the specification.
*
* @see LockModeType
* @see PessimisticLockScope
* @see Timeout
*
* @see EntityManager#lock(Object, LockModeType, LockOption...)
*
* @since 3.2
*/
public interface LockOption {
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*
* @since 2.0
*/
public enum PessimisticLockScope implements FindOption, RefreshOption {
public enum PessimisticLockScope implements FindOption, RefreshOption, LockOption {

/**
* This value defines the default behavior for pessimistic locking.
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/jakarta/persistence/Timeout.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
* @since 3.2
*/
public class Timeout implements FindOption, RefreshOption {
public class Timeout implements FindOption, RefreshOption, LockOption {
private final int milliseconds;

private Timeout(int milliseconds) {
Expand Down
48 changes: 48 additions & 0 deletions spec/src/main/asciidoc/ch03-entity-operations.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,54 @@ public interface EntityManager extends AutoCloseable {
public void lock(Object entity, LockModeType lockMode,
Map<String, Object> properties);
/**
* Lock an entity instance that is contained in the persistence
* context with the specified lock mode type, using specified
* {@linkplain LockOption options}.
* <p>If a pessimistic lock mode type is specified and the entity
* contains a version attribute, the persistence provider must
* also perform optimistic version checks when obtaining the
* database lock. If these checks fail, the
* <code>OptimisticLockException</code> will be thrown.
* <p>If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* <ul>
* <li> the <code>PessimisticLockException</code> will be thrown
* if the database locking failure causes transaction-level
* rollback
* <li> the <code>LockTimeoutException</code> will be thrown if
* the database locking failure causes only statement-level
* rollback
* </ul>
* <p>If a vendor-specific {@link LockOption} is not recognized,
* it is silently ignored.
* <p>Portable applications should not rely on the standard
* {@linkplain Timeout timeout option}. Depending on the database
* in use and the locking mechanisms used by the provider, the
* option may or may not be observed.
* @param entity entity instance
* @param lockMode lock mode
* @param options standard and vendor-specific options
* @throws IllegalArgumentException if the instance is not an
* entity or is a detached entity
* @throws TransactionRequiredException if there is no
* transaction or if invoked on an entity manager which
* has not been joined to the current transaction
* @throws EntityNotFoundException if the entity does not exist
* in the database when pessimistic locking is
* performed
* @throws OptimisticLockException if the optimistic version
* check fails
* @throws PessimisticLockException if pessimistic locking fails
* and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call is made
* @since 3.2
*/
public void lock(Object entity, LockModeType lockMode,
LockOption... options);
/**
* Refresh the state of the instance from the database,
* overwriting changes made to the entity, if any.
Expand Down

0 comments on commit 4e8db0f

Please sign in to comment.