17

トランザクションメソッドが同じクラス内から呼び出された場合、トランザクションで実行されないことを私は知っています。Spring はトランザクション メソッドのプロキシを作成し、それらを try-catch ブロックにラップして、例外が発生した場合はロールバックします。次のシナリオを検討してください。

@Transactional
public void saveAB(A a, B b)
{
    saveA(a);
    saveB(b);
}

@Transactional
public void saveA(A a)
{
    dao.saveA(a);
}

@Transactional
public void saveB(B b)
{
    dao.saveB(b);
}

saveABが別のオブジェクトから呼び出され、 で例外が発生したと仮定すると、正常に完了しましたがsaveB、完了しませんでした。私の知る限り、とはトランザクションではありませんが (同じオブジェクトから呼び出されるため)、トランザクションであるため、ロールバックする必要があります。saveAsaveBsaveAsaveBsaveAB

私が理解できないのは、自己呼び出しがトランザクションを壊すと人々が言うのはなぜですか? 呼び出し元のメソッドがトランザクションである限り、すべてが期待どおりに機能するはずではありませんか? ここに欠けているものはありますか?

4

2 に答える 2

17

私が理解できないのは、自己呼び出しがトランザクションを壊すと人々が言うのはなぜですか?

自己呼び出しがトランザクションを中断するとは聞いたことがありません。私が知っているのは、自己呼び出しが新しいトランザクションを開始しないということだけであり、その理由についてはすでに述べました。

Spring のトランザクション管理仕様のスニペット

プロキシ モード (デフォルト) では、プロキシ経由で着信する外部メソッド呼び出しのみがインターセプトされます。つまり、自己呼び出し、つまり、ターゲット オブジェクト内のメソッドがターゲット オブジェクトの別のメソッドを呼び出している場合、呼び出されたメソッドが @Transactional でマークされていても、実行時に実際のトランザクションは発生しません。


@Transactionからアノテーションを削除するとsaveAB()、そのメソッドが観察され、でアノテーションが付けられていてもトランザクションで実行されなくなります。ただし、呼び出した場合、またはクラス外から呼び出した場合は、期待どおりにトランザクションで実行されます。それが、人々が自己呼び出しに注意するようにアドバイスする理由です。saveA()saveB()@TransactionalsaveA()saveB()

public void saveAB(A a, B b)
{
    saveA(a);
    saveB(b);
}

@Transactional
public void saveA(A a)
{
    dao.saveA(a);
}

@Transactional
public void saveB(B b)
{
    dao.saveB(b);
}

私の見解では、パブリック メソッドを自己呼び出しすることは悪い考えです。

于 2014-05-29T13:34:13.190 に答える