嵌套的transactionTemplate

时间:2013-04-15 16:02:56

标签: java spring jdbctemplate spring-jdbc spring-transactions

我有两种方法可以执行以下操作:

void withdraw(int amount) {
    transactionTemplate.execute(new TransactionCallback() {
        @Override
        public Object doInTransaction() { ... }
    }
}

void deposit(int amount) {
    transactionTemplate.execute(new TransactionCallback() {
        @Override
        public Object doInTransaction() { ... }
    }
}

现在我想定义一个在同一个事务中同时执行的第三个方法:

void transferTo(Account other, int amount) {
    transactionTemplate.execute(new TransactionCallback() {
        @Override
        public Object doInTransaction() {
            withdraw(amount);
            other.deposit(amount);
            return null;
        }
    }
}

事务传播设置为REQUIRED(默认值)。

用例很明显,如果独立调用,我希望withdraw()和deposit()在自己的事务中运行。但是,如果我调用transfer(),我希望所有语句都在同一个事务中运行。

但是当我运行transfer()时,我得到以下异常:

Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@e4b2ed] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@26cc37d2] bound to thread [http-bio-8084-exec-13]
    at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:189)
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:234)

1 个答案:

答案 0 :(得分:2)

嗯,我发现了问题...不是解决我的问题,而是解释为什么我会收到错误。

我使用的事务管理器是 org.springframework.ldap.transaction.compensating.manager.ContextSourceAndDataSourceTransactionManager ,因为我还需要执行一些与LDAP相关的操作。

唯一的问题是 ContextSourceAndDataSourceTransactionManager 不支持嵌套事务。

因此,嵌套的transactionTemplate调用将失败......不方便。

编辑: 进一步调查显示 ContextSourceTransactionManager 也不支持嵌套事务。