web-dev-qa-db-ja.com

Springトランザクション:ExceptionまたはThrowableでのロールバック

代わりに使用するのが理にかなっているのだろうか

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)

Throwableを使用するには

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)

私が理解しているように、Errorをキャッチすると、本当に悪いことが起こった場合でも正しく動作するようになります。それとも助けにならないでしょうか?

15

私が理解しているように、エラーをキャッチすると、本当に悪いことが起こった場合でも正しく動作するようになります。それとも助けにならないでしょうか?

Errorが発生した場合、Springはデフォルトでトランザクションをロールバックするため、rollbackFor = Throwable.classを明示的に指定する必要はありません。

を参照してください12.5.3宣言型トランザクションのロールバック

デフォルトの構成では、Spring Frameworkのトランザクションインフラストラクチャコードは、ランタイムのチェックされていない例外が発生した場合にのみ、トランザクションをロールバックにマークします。つまり、スローされた例外がRuntimeExceptionのインスタンスまたはサブクラスである場合。 (エラーも-デフォルトで-ロールバックになります)。トランザクション方式からスローされたチェック済み例外は、デフォルト構成ではロールバックになりません。

または、 DefaultTransactionAttribute を見てください

public boolean rollbackOn(Throwable ex) {
    return (ex instanceof RuntimeException || ex instanceof Error);
}
25
René Link

@Transactionalを使用しているため、Spring、Hibernate、またはその他のJDBCラッパーを介してデータベース操作を実行していると想定できます。これらのJDBCラッパーは通常、チェック例外をスローしません。JDBCSQLExceptionタイプをラップするランタイム例外をスローします。

@Transactionalは、チェックされていない例外がスローされた場合にのみ、デフォルトでロールバックするように設定されています。

そのようなユースケースを検討してください

@Transactional
public void persistAndWrite(Bean someBean) throws IOException {
    // DB operation
    getSession().save(someBean); 

    // File IO operation which throws IOException
    someFileService.writeToFile(someBean); 
}

ファイルに何かを書き込めなかったからといって、必ずしもDB操作をロールバックする必要はありません。

同様に

@Transactional
public void persistAndThrowOutOfMemory(Bean someBean)  {
    // DB operation
    getSession().save(someBean);

    // consumes all memory, throws OutOfMemoryError
    someService.hugeOperationThrowsOutOfMemoryError(); 
}

一部のサービスによって消費されるメモリが多すぎるために、保存されたエンティティをロールバックする必要はありません。

@Transactionalはオプションを提供します。必要に応じて使用してください。

ロールバックのデフォルト値はエラー例外で登録されますが、uを登録するとtry{}catch{}手動でエラーを上書きするため、この場合は

catch {
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      }

手動で行うか、キャッチを削除するには

また、次のようなトランザクションアノテーションに例外タイプを登録することもできます。

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
1
Ali.Mojtehedy

可能かどうかはわかりませんが、ThrowablesをErrorsのように処理するのは悪いプログラミングスタイルです。この種の致命的なエラーを処理するのは開発者の責任ではありません。あなたが扱えない悪いことが常に起こります。必要に応じて、チェックされた例外を処理する必要があります。これらの例外は、ある種の論理エラーのようにシステムに認識されています。

0
Arsen Alexanyan