Jin Kim
Jin Kim

Reputation: 17732

nested transactionTemplate

I have 2 methods that do the following:

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

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

Now I want to define a third method that does both in the same transaction:

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

Transaction propagation is set to REQUIRED (default).

The use case is obvious, I want withdraw() and deposit() to run in their own transactions if called independently. However if I call transfer(), I want all statements to run within the same transaction.

However when I run transfer(), I get the following exception:

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)

Upvotes: 5

Views: 2943

Answers (1)

Jin Kim
Jin Kim

Reputation: 17732

Well I found the problem... not really a solution to my problem but an explanation as to why I'm getting the error.

The transaction manager I am using is org.springframework.ldap.transaction.compensating.manager.ContextSourceAndDataSourceTransactionManager because I need to perform some LDAP related operations as well.

The only problem is that ContextSourceAndDataSourceTransactionManager does not support nested transactions.

Hence nested transactionTemplate calls will fail... inconvenient.

Edit: Further investigation shows that ContextSourceTransactionManager also does not support nested transactions.

Upvotes: 3

Related Questions