Spring docs トランザクション伝播プロパティを記述する素晴らしい仕事をします。
しかし、これらの各プロパティを素人の言葉でより完全に説明している、よく知られた実際の例が利用できるかどうか疑問に思いました。
PROPAGATION_REQUIRED
class Service {
@Transactional(propagation=Propagation.REQUIRED)
public void doSomething() {
// access a database using a DAO
}
}
DoSomething()が呼び出されると、呼び出し元がまだトランザクションを開始していない場合、新しいトランザクションが開始されます。
このメソッドの呼び出し元がすでにトランザクションを開始している場合、呼び出し元のトランザクションが使用され、新しいトランザクションは作成されません(つまり、1つのトランザクションが実行されます)。
DoSomething()内で例外がスローされた場合、例外はロールバックされます。つまり、呼び出し元にはトランザクションもロールバックされます。
DoSomething()が返されるとき、トランザクションはまだコミットされていません。トランザクションをコミットする(またはロールバックする)のは呼び出し元です。
PROPAGATION_REQUIRES_NEW
class Service {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void doSomething() {
// access a database using a DAO
}
}
DoSomething()が呼び出されると、常に新しいトランザクションが開始されます。
このメソッドの呼び出し元がすでにトランザクション(TxnOuter)を開始している場合、呼び出し元のトランザクションは中断され、新しいトランザクション(TxnInner)が作成されます(つまり、2つのトランザクションが実行されています) )。
DoSomething()内で例外がスローされた場合、TxnInnerはロールバックされますが、呼び出し元(TxnOuter)からの「一時停止」トランザクションは影響を受けません。
DoSomething()が例外なしで戻ると、トランザクション(TxnInner)をコミットします。呼び出し元のトランザクション(TxnOuter)が再開され、別のトランザクションがコミットされたことを認識しません。その後、呼び出し元は、適切と思われるTxnOuterをコミットまたはロールバックできます。
注意すべき重要な点は、データベースがTxnOuterとTxnInnerを完全に独立したトランザクションと見なしているため、2つの独立したコミットがあることです。
PROPAGATION_NESTED
class Service {
@Transactional(propagation=Propagation.NESTED)
public void doSomething() {
// access a database using a DAO
}
}
NESTEDは、JDBCドライバーやデータベースが JDBCセーブポイント をサポートしている場合にのみ使用できます。
DoSomething()が呼び出されると、呼び出し元がまだトランザクションを開始していない場合、新しいトランザクションが開始されます。
このメソッドの呼び出し元がすでにトランザクションを開始している場合、呼び出し元のトランザクションが使用され、新しいトランザクションは作成されません(つまり、1つのトランザクションが実行されます)。ただし、doSomething()が入力されると、トランザクションで「セーブポイント」がマークされます。
DoSomething()内で例外がスローされた場合、トランザクションは部分的に「セーブポイント」にロールバックできます。発信者はトランザクションを続行します。
DoSomething()が例外なしで戻る場合、トランザクション全体をコミットする(またはロールバックする)のは呼び出し元です。
注意すべき重要な点は、データベースは1つのトランザクションのみを表示し、コミットは1つだけであるということです。