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

Diferencia entre LockModeType Jpa

Primero diferenciaría entre bloqueos optimistas y pesimistas, porque son diferentes en su mecanismo subyacente.

El bloqueo optimista está totalmente controlado por JPA y solo requiere una columna de versión adicional en las tablas de base de datos. Es completamente independiente del motor de base de datos subyacente utilizado para almacenar datos relacionales.

Por otro lado, el bloqueo pesimista utiliza el mecanismo de bloqueo proporcionado por la base de datos subyacente para bloquear los registros existentes en las tablas. JPA necesita saber cómo activar estos bloqueos y algunas bases de datos no los admiten o solo parcialmente.

Ahora a la lista de tipos de bloqueo:

  1. LockModeType.Optimistic
    • Si las entidades especifican un campo de versión, este es el valor predeterminado. Para entidades sin una columna de versión, no se garantiza que el uso de este tipo de bloqueo funcione en ninguna implementación de JPA. Este modo generalmente se ignora como lo indica ObjectDB. En mi opinión, solo existe para que pueda calcular el modo de bloqueo dinámicamente y pasarlo más allá, incluso si el bloqueo fuera OPTIMISTA al final. Sin embargo, no es un caso de uso muy probable, pero siempre es un buen diseño de API proporcionar una opción para hacer referencia incluso al valor predeterminado.
  • Ejemplo:

       `LockModeType lockMode = resolveLockMode();
     A a = em.find(A.class, 1, lockMode);`
    
  1. LockModeType.OPTIMISTIC_FORCE_INCREMENT
  • Esta es una opción que rara vez se usa. Pero podría ser razonable, si desea bloquear la referencia a esta entidad por parte de otra entidad. En otras palabras, desea bloquear el trabajo con una entidad incluso si no se modifica, pero se pueden modificar otras entidades en relación con esta entidad.
  • Ejemplo:Tenemos la entidad Libro y Estante. Es posible agregar Book to Shelf, pero el libro no tiene ninguna referencia a su estante. Es razonable bloquear la acción de mover un libro a un estante, para que un libro no termine en otro estante (debido a otra transacción) antes del final de esta transacción. Para bloquear esta acción, no es suficiente bloquear la entidad del estante del libro actual, ya que el libro no tiene que estar todavía en un estante. Tampoco tiene sentido bloquear todas las estanterías de destino, ya que probablemente serían diferentes en diferentes transacciones. Lo único que tiene sentido es bloquear la entidad del libro en sí, incluso si en nuestro caso no se cambia (no tiene referencia a su estantería).
  1. LockModeType.PESSIMISTIC_READ
  • este modo es similar a LockModeType.PESSIMISTIC_WRITE , pero diferente en una cosa:hasta que alguna transacción bloquee la escritura en la misma entidad, no debería bloquear la lectura de la entidad. También permite bloquear otras transacciones usando LockModeType.PESSIMISTIC_READ . Las diferencias entre los bloqueos WRITE y READ están bien explicadas aquí (ObjectDB) y aquí (OpenJPA). Si una entidad ya está bloqueada por otra transacción, cualquier intento de bloquearla generará una excepción. Este comportamiento se puede modificar para esperar un tiempo a que se libere el bloqueo antes de lanzar una excepción y revertir la transacción. Para hacer eso, especifique el javax.persistence.lock.timeout pista con el número de milisegundos a esperar antes de lanzar la excepción. Hay varias formas de hacer esto en varios niveles, como se describe en el tutorial de Java EE.
  1. LockModeType.PESSIMISTIC_WRITE
  • esta es una versión más fuerte de LockModeType.PESSIMISTIC_READ . Cuando WRITE lock está en su lugar, JPA con la ayuda de la base de datos evitará que cualquier otra transacción lea la entidad, no solo para escribir como con READ bloquear.
  • No se prescribe la forma en que esto se implementa en un proveedor de JPA en cooperación con la base de datos subyacente. En su caso con Oracle, diría que Oracle no proporciona algo parecido a READ cerrar con llave. SELECT...FOR UPDATE es más bien un WRITE cerrar con llave. Puede ser un error en hibernate o simplemente una decisión que, en lugar de implementar READ "más suave" personalizado lock, el "más difícil" WRITE en su lugar se utiliza el candado. Esto en su mayoría no rompe la consistencia, pero no mantiene todas las reglas con READ Cerraduras. Podría ejecutar algunas pruebas simples con READ bloqueos y transacciones de ejecución prolongada para averiguar si más transacciones pueden adquirir READ bloqueos en la misma entidad. Esto debería ser posible, mientras que no con WRITE cerraduras.
  1. Tipo de modo de bloqueo.PESSIMISTIC_FORCE_INCREMENT
  • este es otro modo de bloqueo que rara vez se usa. Sin embargo, es una opción donde necesitas combinar PESSIMISTIC y OPTIMISTIC mecanismos. Usando PESSIMISTIC_WRITE simple fallaría en el siguiente escenario:
    1. la transacción A usa bloqueo optimista y lee la entidad E
    2. la transacción B adquiere un bloqueo de ESCRITURA en la entidad E
    3. la transacción B se compromete y libera el bloqueo de E
    4. la transacción A actualiza E y confirma
  • en el paso 4, si la transacción B no incrementa la columna de versión, nada impide que A sobrescriba los cambios de B. Modo de bloqueo LockModeType.PESSIMISTIC_FORCE_INCREMENT obligará a la transacción B a actualizar el número de versión y provocará que la transacción A falle con OptimisticLockException , aunque B estaba utilizando el bloqueo pesimista.
  1. TipoModoBloqueo.NINGUNO
  • este es el valor predeterminado si las entidades no proporcionan un campo de versión. Significa que si no está habilitado el bloqueo, los conflictos se resolverán con el mejor esfuerzo y no se detectarán. Este es el único modo de bloqueo permitido fuera de una transacción