transacciones transaccionalidad transaccion setautocommit parametros manejo ejemplo consultas con java database hibernate concurrency transactions

transaccionalidad - transaccion sql server java



Niveles de aislamiento de transacción variable por solicitud (4)

Si está usando Spring, puede usar algo como esto:

@Transactional(isolation = Isolation.SERIALIZABLE)

y funciona para el JpaTransactionManager . Si está utilizando JtaTransactionManager, el aislamiento de transacción de alcance de solicitud no se propaga, ya que este es el comportamiento de JTA predeterminado.

Debido a que JTA no admite niveles de aislamiento del ámbito de la transacción, Spring ofrece el IsolationLevelDataSourceRouter para superar esta deficiencia al usar el servidor de aplicaciones JTA DataSources.

Debido a que la mayoría de las implementaciones de DataSource solo pueden tomar un nivel de aislamiento de transacción predeterminado, podemos tener múltiples DataSources, cada una de las cuales brinda conexiones para un nivel de aislamiento de transacción específico.

La configuración de nivel de aislamiento de transacción lógica (por ejemplo, @Transactional) es introspectiva por IsolationLevelDataSourceRouter y la solicitud de adquisición de conexión se delega a una implementación de DataSource específica que puede servir a una conexión JDBC con la misma configuración de nivel de aislamiento de transacción.

Por lo tanto, incluso en entornos JTA, el enrutador de aislamiento de transacciones puede ofrecer una solución independiente del proveedor para anular el nivel de aislamiento de base de datos predeterminado por transacción.

Java EE no es compatible con la configuración de aislamiento de transacción a nivel de método.

El nivel de aislamiento SERIALIZABLE lo protegerá contra lecturas no repetibles y lecturas ficticias, e incluso SERIALIZABLE no lo protege contra las actualizaciones perdidas en transacciones lógicas de solicitudes múltiples .

El bloqueo optimista escala mejor cuando se utilizan las entidades separadas (a partir de que se cargaron cuando se inició la transacción lógica).

Estoy escribiendo una pequeña aplicación de subasta, y es muy importante que mis ofertas se registren con certeza. Después de todo, los últimos dos segundos de la subasta son momentos críticos para los compradores, y no puedo arriesgarlos a pujar simultáneamente y tener una condición de carrera.

Y, por supuesto, para eso es el aislamiento de transacción. Puedo establecer mi nivel de aislamiento en serializable, y estamos listos.

¿Pero qué pasa con todas las demás solicitudes? Si las personas están viendo perfiles o enviando mensajes, estas solicitudes no necesitan estar cerca de ese tipo de aislamiento de transacción. Un nivel de aislamiento de lectura confirmada es perfectamente aceptable para esas solicitudes.

Estoy configurando mi nivel de transacción como parte de mi propiedad de hibernate.connection.isolation , pero realmente me gustaría poder hacer algo como session.setTransactionIsolation(newIsolation) por solicitud.


Para este caso, utilizaré el bloqueo optimista en los objetos de ofertas ... la condición de carrera aún se producirá, pero se detectará cuando la transacción intente confirmar los cambios en los objetos de tu dominio (lanzando una excepción si la versión revisada se actualizó) por otro hilo).

Por lo tanto, cualquier cambio en cualquier objeto de oferta será casi serializable (digo "casi" porque para ser serializable, las transacciones fallidas deberán ser atrapadas y reintentadas de alguna manera).


si falla el ajuste del nivel de aislamiento por transacción, siempre puede serializar manualmente una operación específica en su código (sincronización, semáforos, etc.). sin embargo, tenga en cuenta que no es escalable (solo jvm, operación única, fácil de pasar accidentalmente de otras partes del código)


Session session = getSession(dataSource, sessionFactory, Connection.TRANSACTION_SERIALIZABLE); public Session getSession(DataSource dataSource, SessionFactory sessionFactory, int isolationLevel){ // Get connection from current dataSource and set new isolation Connection connectionWithNewIsolation = dataSource.getConnection(); connectionWithNewIsolation.setTransactionIsolation(isolationLevel); // Get session from current sessionFactory with the new isolation Session session = sessionFactory.openSession(connectionWithNewIsolation); // Hibernate 4.3 //SessionFactory.openStatelessSession(Connection connection) // Hibernate 3.6 //SessionFactory.openSession(Connection connection) //SessionFactory.openStatelessSession(Connection connection) return session; }