トランザクション シナリオでは、例外がスローされてキャッチされた後、ロールバックが必要な場合は、トランザクションを手動でロールバックする必要があります。
@Override
@Transactional
public void save(User user) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
// execute your business logic here
//db operation
} catch (Exception ex) {
//手动回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw ex;
}
}
デフォルトでは、Spring トランザクション フレームワークは、RuntimeException と未チェック例外がスローされた場合にのみトランザクションをロールバックします (エラーのデフォルト - トランザクション ロールバック)。ただし、チェック済み例外がスローされた場合、トランザクションはロールバックされません。
このデフォルトを変更したい場合は、シーンに応じて設定できます。
また、チェック済み例外がスローされたときにトランザクションをロールバックします: @Transactional(rollbackFor=Exception.class)
チェックされていない例外がスローされたときにトランザクションをロールバックしません: @Transactional(notRollbackFor=RunTimeException.class)
トランザクション管理は必要ありません: @Transactional(propagation=Propagation. NOT_SUPPORTED)
注: try{}catch{} によって例外がキャッチされた場合、トランザクションはロールバックされません。トランザクションをロールバックしたい場合は、try{}catch{throw Exception} をスローする必要があります。
Spring チームからの提案は、クラスが実装するインターフェイスではなく、具体的なクラス (またはクラスのメソッド) に対して @Transactional アノテーションを使用することです。もちろん、インターフェイスで @Transactional アノテーションを使用することもできますが、これはインターフェイスベースのプロキシを設定している場合にのみ機能します。アノテーションは継承されないため、クラスベースのプロキシを使用している場合、トランザクション設定はクラスベースのプロキシによって認識されず、オブジェクトはトランザクション プロキシによってラップされません(深刻なものであるかどうかが検証されます)。したがって、Spring チームのアドバイスに従って、具体的なクラスに @Transactional アノテーションを使用してください。
@Transactional アノテーションはメソッドを識別し、処理プロセスは可能な限り単純になります。特にロックのあるトランザクション メソッドの場合、トランザクションに配置できない場合は、トランザクションに配置しないことをお勧めします。通常のデータベース クエリ操作はトランザクションの前に実行でき、クエリの追加、削除、変更、ロックなどの操作はトランザクション内で実行できます。