4

次のことを行う2つの方法があります。

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

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

ここで、同じトランザクションで両方を行う 3 番目のメソッドを定義したいと思います。

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)
4

1 に答える 1