Spring programmatic transaction management caveat?
java, spring, transactions
Solution
Yes, it's correct.
Any code that uses raw `Connection`s should obtain them from the `DataSource` in special way in order to participate in transactions managed by Spring (12.3.8 DataSourceTransactionManager):
Application code is required to retrieve the JDBC connection through DataSourceUtils.getConnection(DataSource) instead of Java EE's standard DataSource.getConnection.
Another option (if you cannot change code that calls `getConnection()`) is to wrap your `DataSource` with `TransactionAwareDataSourceProxy`.
Problem
Spring supports programmatic transaction which give us fine grained control over TX management. According to Spring Documentation, One can use programmatic TX management by: 1. utilizing Spring's TransactionTemplate: ``` transactionTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { try { updateOperation1(); updateOperation2(); } catch (SomeBusinessExeption ex) { status.setRollbackOnly(); } } }); ``` 2. leveraging PlatformTransactionManager directly(inject a PlatformTransactionManager implementation into 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); ``` for the sake of simplification, let's say we are dealing with JDBC database operation. I am wondering for any database operations happened at `updateOperation1(),updateOperation2()` in the second snippet, either it is implemented with `JDBCTemplate` or `JDBCDaoSupport`, if not, the operation is actually not performed within any transaction, is it? My analysis is that if we don't use `JDBCTemplate` or `JDBCDaoSupport`, we inevitably will create/retrieve connection from datasource management. the connection we get is of course not the connection used by `PlatformTransactionManager` underlying to manage transaction. I dug Spring source code and skim related class found that `PlatformTransactionManager` will try to retrieve a connection contained in `ConnectionHolder` which in return retrieved from `TransactionSynchronizationManager`. I also found `JDBCTemplate` and `JDBCDaoSupport,` also try to get connection with similar routine from `TransactionSynchronizationManager.` Because `TransactionSynchronizationManager` manages many resource including connection per thread(basically use `Threadlocal` to ensure one thread get its own unique instance of the managed resource) So I think the connection retrieved by PlatformTransactionManager and `JDBCTemplate` or `JDBCDaoSupport` is just same, this can explain how spring programmatic transaction ensure `updateOperation1(),updateOperation2()` were guarded by transaction. Is my analysis correct? if it is, why Spring documentation hasn't emphasized this caveat?