首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TransactionTemplate和TransactionManager连接对象

TransactionTemplate和TransactionManager连接对象
EN

Stack Overflow用户
提问于 2013-08-27 02:44:54
回答 1查看 10.7K关注 0票数 3

我的DAO中的以下代码运行得很好。

代码语言:javascript
复制
public void insert(final Person person) {
    transactionTemplate.execute(new TransactionCallback<Void>() {
        public Void doInTransaction(TransactionStatus txStatus) {
            try {
                getJdbcTemplate().execute("insert into person(username, password) values ('" + person.getUsername() + "','" + person.getPassword() + "')");
            } catch (RuntimeException e) {
                txStatus.setRollbackOnly();
                throw e;
            }
            return null;
        }
    });
}

下面是我的spring配置。

代码语言:javascript
复制
<bean id="derbyds" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
    <property name="username" value="app" />
    <property name="password" value="app" />
    <property name="url" value="jdbc:derby:mytempdb" />
</bean>

<bean id="persondaojdbc" class="com.napp.dao.impl.PersonDaoJdbcImpl">
    <property name="dataSource" ref="derbyds" />
    <property name="transactionTemplate">
        <bean class="org.springframework.transaction.support.TransactionTemplate">
            <property name="transactionManager" ref="transactionManager" />
        </bean>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="derbyds"/>
</bean>

我想知道的是

代码语言:javascript
复制
<bean id="persondaojdbc" class="com.napp.dao.impl.PersonDaoJdbcImpl">
    <property name="dataSource" ref="derbyds" />
    <property name="transactionTemplate">
        <bean class="org.springframework.transaction.support.TransactionTemplate">
            <property name="transactionManager" ref="transactionManager" />
        </bean>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="derbyds"/>
</bean>

现在,TransactionManager和代码(在我的例子中是jdbc模板)必须在相同的连接上操作。我假设它们都是从DataSource获取Connection对象。当你多次调用getConnection时,你会得到不同的连接指令。spring如何确保TransactionManager和JdbcTemplate最终获得相同的connection对象。我的理解是,如果这种情况没有发生,回滚或提交就不会起作用,对吗?有没有人能解释一下这个问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-27 02:58:22

如果查看JdbcTemplate (其中一种execute(...)方法)的代码,您将看到

代码语言:javascript
复制
Connection con = DataSourceUtils.getConnection(getDataSource());

它试图从注册了ConnectionConnectionHolder中检索TransactionSynchronizationManager

如果没有这样的对象,它只是从DataSource获得一个连接并注册它(如果它在事务环境中,即。您有一个事务管理器)。否则,它会立即返回注册的对象。

这是代码(去掉日志和其他东西)

代码语言:javascript
复制
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
    conHolder.requested();
    if (!conHolder.hasConnection()) {
        conHolder.setConnection(dataSource.getConnection());
    }
    return conHolder.getConnection();
}
// Else we either got no holder or an empty thread-bound holder here.

Connection con = dataSource.getConnection();

// flag set by the TransactionManager
if (TransactionSynchronizationManager.isSynchronizationActive()) {
    // Use same Connection for further JDBC actions within the transaction.
    // Thread-bound object will get removed by synchronization at transaction completion.
    ConnectionHolder holderToUse = conHolder;
    if (holderToUse == null) {
        holderToUse = new ConnectionHolder(con);
    }
    else {
        holderToUse.setConnection(con);
    }
    holderToUse.requested();
    TransactionSynchronizationManager.registerSynchronization(
                new ConnectionSynchronization(holderToUse, dataSource));
    holderToUse.setSynchronizedWithTransaction(true);
    if (holderToUse != conHolder) {
        TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
    }
}

return con;

您会注意到JdbcTemplate试图

代码语言:javascript
复制
finally {
    DataSourceUtils.releaseConnection(con, getDataSource());
}

释放连接,但只有在非事务性环境中才会发生这种情况。

如果它不是外部管理的(即未绑定到线程),则为

因此,在事务性世界中,JdbcTemplate将重用相同的Connection对象。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18450866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档