Spring 支持编程事务,这让我们可以对 TX 管理进行细粒度控制。根据 Spring 文档,可以通过以下方式使用编程式 TX 管理:
1. 利用 Spring 的 TransactionTemplate:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
updateOperation1();
updateOperation2();
} catch (SomeBusinessExeption ex) {
status.setRollbackOnly();
}
} });
2。直接利用 PlatformTransactionManager(将 PlatformTransactionManager 实现注入(inject) 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);
为了简单起见,假设我们正在处理 JDBC 数据库操作。
我想知道在第二个片段中 updateOperation1(),updateOperation2()
发生的任何数据库操作,它是用 JDBCTemplate
还是 JDBCDaoSupport< 实现的
,如果不是,则该操作实际上没有在任何事务中执行,是吗?
我的分析是,如果我们不使用JDBCTemplate
或JDBCDaoSupport
,我们将不可避免地从数据源管理中创建/检索连接。我们得到的连接当然不是PlatformTransactionManager
底层用来管理事务的连接。
我挖掘了 Spring 源代码并浏览了相关类,发现 PlatformTransactionManager
将尝试检索包含在 ConnectionHolder
中的连接,而后者又从 TransactionSynchronizationManager
。我还找到了 JDBCTemplate
和 JDBCDaoSupport,
也尝试从 TransactionSynchronizationManager.
因为 TransactionSynchronizationManager
管理许多资源,包括每个线程的连接(基本上使用 Threadlocal
来确保一个线程获得其自己唯一的托管资源实例)
所以我认为 PlatformTransactionManager 和 JDBCTemplate
或 JDBCDaoSupport
检索到的连接是一样的,这可以解释 spring programmatic transaction 如何确保 updateOperation1(),updateOperation2( )
由事务保护。
我的分析正确吗?如果是,为什么 Spring 文档没有强调这个警告?
最佳答案
是的,这是正确的。
任何使用原始 Connection
的代码都应该以特殊方式从 DataSource
中获取它们,以便参与由 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.
另一个选项(如果您不能更改调用 getConnection()
的代码)是用 TransactionAwareDataSourceProxy
包装您的 DataSource
.
关于java - Spring程序化事务管理警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11087873/