2012-06-18 11 views
5

Spring admite transacciones programáticas que nos dan un control detallado de la administración de TX. De acuerdo con la documentación de primavera, se puede utilizar la gestión programática TX por:
1. utilizando TransactionTemplate de primavera:Spring programmatic transaction management caveat?

transactionTemplate.execute(new TransactionCallbackWithoutResult() { 

protected void doInTransactionWithoutResult(TransactionStatus status) { 
    try { 
     updateOperation1(); 
     updateOperation2(); 
    } catch (SomeBusinessExeption ex) { 
     status.setRollbackOnly(); 
    } 
} }); 

2. aprovechando PlatformTransactionManager directamente (inyectar una aplicación PlatformTransactionManager en DAO):

DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 
def.setName("SomeTxName"); 
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 

//txManager is a reference to PlatformTransactionManager 
TransactionStatus status = txManager.getTransaction(def); 
try { 
    updateOperation1(); 
    updateOperation2(); 
} 
catch (MyException ex) { 
    txManager.rollback(status); 
    throw ex; 
} 
txManager.commit(status); 

de En aras de la simplificación, digamos que estamos tratando con el funcionamiento de la base de datos JDBC.

Me pregunto para cualquier operación de base de datos ocurrió en updateOperation1(),updateOperation2() en el segundo fragmento, ya sea que se implementa con JDBCTemplate o JDBCDaoSupport, si no, la operación es en realidad no se lleva a cabo dentro de cualquier transacción, ¿verdad?

Mi análisis es que si no usamos JDBCTemplate o JDBCDaoSupport, inevitablemente crearemos/recuperaremos la conexión de la gestión de la fuente de datos. la conexión que obtenemos es, por supuesto, no la conexión utilizada por PlatformTransactionManager subyacente para administrar la transacción.

Cavé código fuente de Primavera y descremada clase relacionada encontró que PlatformTransactionManager a tratar de recuperar una conexión contenida en ConnectionHolder que a su vez recuperada de TransactionSynchronizationManager. También encontré JDBCTemplate y JDBCDaoSupport, también tratar de obtener la conexión con la rutina similar de TransactionSynchronizationManager.

Debido TransactionSynchronizationManager administra muchos recursos incluyendo la conexión por hilo (básicamente utilizar Threadlocal para asegurar un hilo obtener su propia instancia única del recurso gestionado)

Así que creo que la conexión recuperada por PlatformTransactionManager y JDBCTemplate o JDBCDaoSupport es exactamente la misma, esto puede explicar cómo la transacción programática de primavera garantiza que updateOperation1(),updateOperation2() estén protegidos por transacción.

¿Mi análisis es correcto? si es así, ¿por qué la documentación de Spring no ha enfatizado esta advertencia?

Respuesta

2

Sí, es correcto.

Cualquier código que utiliza primas Connection s deben obtenerlos de la DataSource de manera especial con el fin de participar en las operaciones gestionadas por la primavera (12.3.8 DataSourceTransactionManager): Se requiere

código de la aplicación para recuperar la conexión JDBC a través DataSourceUtils .getConnection (DataSource) en lugar del estándar DataSource.getConnection de Java EE.

Otra opción (si no se puede cambiar código que llama getConnection()) es envolver su DataSource con TransactionAwareDataSourceProxy.

Cuestiones relacionadas