¿Por qué necesito Transacción en Hibernate para operaciones de solo lectura?
¿La siguiente transacción bloquea la base de datos?
Código de ejemplo para obtener de DB:
Transaction tx = HibernateUtil.getCurrentSession().beginTransaction(); // why begin transaction?
//readonly operation here
tx.commit() // why tx.commit? I don't want to write anything
¿Puedo usar en session.close()
lugar de tx.commit()
?
java
database
hibernate
transactions
database-connection
user93796
fuente
fuente
Respuestas:
Es posible que tenga motivos para marcar las transacciones como de solo lectura.
autocommit=true
si no se estableció explícitamente una opción diferente.@Transactional(readonly=true)
, Spring establecerá la transacción JDBC en un modo de solo lectura, por lo que dictará si es realmente posible escribir en la base de datos en el alcance de esta transacción. Si su arquitectura es engorrosa y algunos miembros del equipo pueden optar por colocar una consulta de modificación donde no se espera, este indicador le indicará el lugar problemático.En resumen, puede ir en ambos sentidos, pero debe comprender las consecuencias.
fuente
Todas las declaraciones de la base de datos se ejecutan dentro del contexto de una transacción física, incluso cuando no declaramos explícitamente los límites de la transacción (BEGIN / COMMIT / ROLLBACK).
Si no declara los límites de la transacción explícitamente, entonces cada declaración deberá ejecutarse en una transacción separada (
autocommit
modo). Esto incluso puede llevar a abrir y cerrar una conexión por declaración a menos que su entorno pueda lidiar con el enlace de conexión por subproceso.Declarar un servicio como
@Transactional
le dará una conexión durante toda la duración de la transacción, y todas las declaraciones utilizarán esa única conexión de aislamiento. Esto es mucho mejor que no utilizar transacciones explícitas en primer lugar.En aplicaciones grandes, es posible que tenga muchas solicitudes simultáneas, y la reducción de la tasa de solicitudes de adquisición de conexión de base de datos definitivamente mejorará el rendimiento general de su aplicación.
JPA no impone transacciones en operaciones de lectura. Solo las escrituras terminan lanzando una excepción de transacción requerida en caso de que olvide iniciar un contexto transaccional. Sin embargo, siempre es mejor declarar los límites de las transacciones incluso para las transacciones de solo lectura (en Spring le
@Transactional
permite marcar transacciones de solo lectura, lo que tiene un gran beneficio de rendimiento).fuente
De hecho, las transacciones bloquean la base de datos (los buenos motores de base de datos manejan bloqueos simultáneos de manera sensata) y son útiles con el uso de solo lectura para garantizar que ninguna otra transacción agregue datos que hagan que su vista sea inconsistente. Siempre desea una transacción (aunque a veces es razonable ajustar el nivel de aislamiento, es mejor no hacerlo para empezar); si nunca escribe en la base de datos durante su transacción, tanto la confirmación como la reversión de la transacción resultan ser iguales (y muy baratas).
Ahora, si tiene suerte y sus consultas contra la base de datos son tales que el ORM siempre las asigna a consultas SQL únicas, puede salirse con la suya sin transacciones explícitas , confiando en el comportamiento de confirmación automática incorporado en la base de datos, pero los ORM son sistemas relativamente complejos. por lo tanto, no es seguro confiar en tal comportamiento a menos que trabaje mucho más para verificar lo que realmente hace la implementación. Escribir los límites de transacción explícitos es mucho más fácil de hacer bien (especialmente si puede hacerlo con AOP o alguna técnica similar impulsada por ORM; desde Java 7 en adelante, también se podría usar try-with-resources, supongo).
fuente
No importa si solo lee o no, la base de datos aún debe realizar un seguimiento de su conjunto de resultados, porque otros clientes de la base de datos pueden querer escribir datos que cambiarían su conjunto de resultados.
He visto programas defectuosos para matar sistemas de bases de datos enormes, porque solo leen datos, pero nunca se comprometen, lo que obliga a que el registro de transacciones crezca, porque la base de datos no puede liberar los datos de la transacción antes de COMMIT o ROLLBACK, incluso si el cliente no hizo nada por horas.
fuente