sql >> Base de Datos >  >> RDS >> Oracle

¿Cómo especificar el tiempo de espera de @lock en la consulta jpa de datos de primavera?

Para Spring Data 1.6 o superior

@Lock es compatible con los métodos CRUD a partir de la versión 1.6 de Spring Data JPA (de hecho, ya existe un hito disponible). Ver este boleto para más detalles.

Con esa versión simplemente declaras lo siguiente:

interface WidgetRepository extends Repository<Widget, Long> {

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Widget findOne(Long id);
}

Esto hará que la parte de implementación de CRUD del proxy del repositorio de respaldo aplique el LockModeType configurado al find(…) llama al EntityManager .

Por otro lado,

Para la versión anterior de Spring Data 1.6

El @Lock pesimista de Spring Data las anotaciones solo se aplican (como usted señaló) a las consultas. No hay anotaciones que yo sepa que puedan afectar una transacción completa. Puede crear un findByOnePessimistic método que llama a findByOne con un bloqueo pesimista o puede cambiar findByOne para obtener siempre un bloqueo pesimista.

Si quisiera implementar su propia solución, probablemente podría hacerlo. Debajo del capó, el @Lock la anotación es procesada por LockModePopulatingMethodIntercceptor que hace lo siguiente:

TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);

Podría crear algún administrador de bloqueo estático que tuviera un ThreadLocal<LockMode> miembro variable y luego tener un aspecto envuelto alrededor de cada método en cada repositorio que llamó a bindResource con el modo de bloqueo establecido en ThreadLocal. Esto le permitiría configurar el modo de bloqueo por subproceso. Luego podría crear su propio @MethodLockMode anotación que envolvería el método en un aspecto que establece el modo de bloqueo específico del subproceso antes de ejecutar el método y lo borra después de ejecutar el método.

Enlace de recursos:

  1. ¿Cómo habilitar LockModeType.PESSIMISTIC_WRITE al buscar entidades con Spring Data JPA?
  2. Cómo agregar un método personalizado método para Spring Data JPA
  3. Tiempo de espera de Spring Data Pessimistic Lock con Postgres
  4. API de consulta JPA

Varios ejemplos de tiempo de espera de bloqueo pesimista

Establecer un bloqueo pesimista

Un objeto de entidad se puede bloquear explícitamente mediante el método de bloqueo:

em.lock(employee, LockModeType.PESSIMISTIC_WRITE);

El primer argumento es un objeto de entidad. El segundo argumento es el modo de bloqueo solicitado.

Una TransactionRequiredException se lanza si no hay una transacción activa cuando se llama al bloqueo porque el bloqueo explícito requiere una transacción activa.

Una LockTimeoutException se lanza si no se puede otorgar el bloqueo pesimista solicitado:

  • UN PESSIMISTIC_READ la solicitud de bloqueo falla si otro usuario (que está representado por otra instancia de EntityManager) actualmente tiene un PESSIMISTIC_WRITE bloqueo en ese objeto de la base de datos.
  • UN PESSIMISTIC_WRITE la solicitud de bloqueo falla si otro usuario actualmente tiene un PESSIMISTIC_WRITE candado o un PESSIMISTIC_READ bloquear ese objeto de la base de datos.

Configuración de la sugerencia de consulta (ámbitos)

Las sugerencias de consulta se pueden establecer en los siguientes ámbitos (de global a local):

Para toda la unidad de persistencia, usando un persistence.xml propiedad:

<properties>
   <property name="javax.persistence.query.timeout" value="3000"/>
</properties>

Para una EntityManagerFactory - usando createEntityManagerFacotory método:

Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 4000);
EntityManagerFactory emf =
  Persistence.createEntityManagerFactory("pu", properties);

Para un EntityManager:usando createEntityManager método:

Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 5000);
EntityManager em = emf.createEntityManager(properties);

o usando el método setProperty:

em.setProperty("javax.persistence.query.timeout", 6000);

Para una named query definición - usando las hints elemento:

@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
    hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})

Para una ejecución de consulta específica, usando setHint método (antes de la ejecución de la consulta):

query.setHint("javax.persistence.query.timeout", 8000);

Enlace de recursos:

  1. Bloqueo en JPA
  2. Tiempo de espera de bloqueo pesimista