java - Spring程序化事务管理警告?

标签 java spring transactions

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< 实现的,如果不是,则该操作实际上没有在任何事务中执行,是吗?

我的分析是,如果我们不使用JDBCTemplateJDBCDaoSupport,我们将不可避免地从数据源管理中创建/检索连接。我们得到的连接当然不是PlatformTransactionManager底层用来管理事务的连接。

我挖掘了 Spring 源代码并浏览了相关类,发现 PlatformTransactionManager 将尝试检索包含在 ConnectionHolder 中的连接,而后者又从 TransactionSynchronizationManager。我还找到了 JDBCTemplateJDBCDaoSupport, 也尝试从 TransactionSynchronizationManager.

获取与类似例程的连接

因为 TransactionSynchronizationManager 管理许多资源,包括每个线程的连接(基本上使用 Threadlocal 来确保一个线程获得其自己唯一的托管资源实例)

所以我认为 PlatformTransactionManager 和 JDBCTemplateJDBCDaoSupport 检索到的连接是一样的,这可以解释 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/

相关文章:

java - 如何更改tomcat或jetty下的Java webapp 'WEB-INF path'约定

java - 使用HTTPS客户端向服务器的440端口发送请求

java - web.xml 中的错误页面配置不起作用

java - 如何在 Camel 中跨步骤使用相同的事务?

java - 为什么对于大量数据,函数式比命令式快,而对于少量数据,函数式比命令式慢?

java - 实现社交媒体登录到spring security

java - 在 Spring 中确定不支持的媒体类型最理想的时间/地点?

java - 如何在上下文初始化后创建 session bean

transactions - 获取已发布交易的 MAPP 协议(protocol)是什么?

java - 对来自多个模式的表执行数据库操作的服务方法的事务管理器