¿Necesita una transacción de base de datos para leer datos?

Cuando trato de leer datos de la base de datos, al menos usando

((Session)em.getDelegate()).createCriteria()

una excepción es throws diciendo que una transacción no está presente.

Cuando agrego la anotación:

 @Transactional( value = SomeClass.TRANSACTIONAL_MANAGER, propagation = Propagation.SUPPORTS, readOnly = true ) 

funciona bien.

Sin embargo, dado que la lectura ocurrirá millones de veces por segundo para acceder y leer datos, quiero asegurarme de que nuestro entorno no se tape innecesariamente.

De lo contrario, ¿cuál es el costo de crear una transacción de Propagation.Supports solo lectura?

¿No puedo crear una consulta de criterios de Hibernate sin una transacción, en combinación con Spring?

Todas las declaraciones de base de datos se ejecutan dentro del contexto de una transacción física, incluso cuando no declaramos explícitamente límites de transacción (BEGIN / COMMIT / ROLLBACK).

Si no declara límites de transacción, cada sentencia deberá ejecutarse en una transacción por separado (modo de autocommit ). Esto puede incluso llevar a abrir y cerrar una conexión por enunciado a menos que su entorno pueda ocuparse del enlace de conexión por hilo.

La statement de un servicio como @Transactional le dará una conexión durante toda la duración de la transacción, y todas las declaraciones usarán esa única conexión de aislamiento. Esto es mucho mejor que no usar 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 solicitud de adquisición de la conexión de la base de datos definitivamente mejorará el rendimiento general de la aplicación.

JPA no aplica 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 @Transactional permite marcar transacciones de solo lectura, lo que tiene un gran beneficio de rendimiento).

Ahora, si utiliza límites declarativos de transacción (por ejemplo, @Transactional ), debe asegurarse de que la adquisición de la conexión de la base de datos se demore hasta que se ejecute una instrucción JDBC. En JTA, este es el comportamiento predeterminado. Al usar RESOURCE_LOCAL, debe configurar la propiedad de configuración hibernate.connection.provider_disables_autocommit y asegurarse de que el grupo de conexiones subyacente esté configurado para desactivar el modo de confirmación automática.

De acuerdo con mi experiencia con la implementación de JPA en J2EE , siempre se necesita un administrador de transacciones para realizar la seguridad de operación de CRUD , al garantizar una reversión para preservar la integridad de los datos.

Las aplicaciones empresariales usan diferentes recursos para guardar datos y enviar mensajes como una base de datos o cola de mensajes. Si queremos consultar estos recursos secuencialmente y cancelar toda la operación una vez que ocurre un problema, tenemos que poner esta consulta en una unidad de trabajo para que se ejecute como un todo.

Podrías definirlo:

  • mediante el uso de anotaciones relacionadas (como se muestra en las preguntas); de esta forma, el contenedor carga automáticamente el administrador de transacciones para un contexto de persistencia dado;

  • al inyectar manualmente el administrador de transacciones, de la siguiente manera:

     public class sample { @PersistenceContext EntityManager em; // Injected transaction manager @Inject UserTransaction utx; private static final String[] GAME_TITLES = { "Super Mario Brothers", "Mario Kart", "F-Zero" }; private void clearData() throws Exception { utx.begin(); em.joinTransaction(); System.out.println("Dumping old records..."); em.createQuery("delete from Game").executeUpdate(); utx.commit(); } private void insertData() throws Exception { utx.begin(); em.joinTransaction(); System.out.println("Inserting records..."); for (String title : GAME_TITLES) { Game game = new Game(title); em.persist(game); } utx.commit(); // clear the persistence context (first-level cache) em.clear(); } // ... } 

Spring Data , como implementación de especificaciones JPA, puede seguir el mismo enfoque.

Puede encontrar más información leyendo el siguiente artículo: Java_Persistence / Transactions .