web-dev-qa-db-ja.com

春:チェックされた例外の自動ロールバック

RuntimeExceptions以外でロールバックするようにSpringを構成する1つの方法は、サービスクラスで@Transactional(rollbackFor=...)アノテーションを使用することです。このアプローチの問題は、実際には冗長に見えるほとんどすべてのサービスクラスに対して(rollbackFor = ...)を定義する必要があることです。


私の質問:Springトランザクションマネージャーが_@Transactional_アノテーションごとに宣言せずに、発生するたびに非RuntimeExceptionでロールバックするようにデフォルトの動作を構成する方法はありますか。 EJBの例外クラスで@ApplicationException(rollback=true)アノテーションを使用するようなもの。

11
sara

@Transactionalを使用してアプリケーションレベルでそれを行うことはできませんが、次のことができます。

バリアント1:@ Transactionalアノテーションを拡張し、rollbackforのデフォルト値として配置します。ただし、必要な場合にのみ、未チェックの例外のロールバックを設定します。これにより、確実な場合にのみロールバックを制御でき、@ Transactional(rollbackFor = MyCheckedException.class)の過去のコピーを回避できます。

お気に入り:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(rollbackFor=MyCheckedException.class)
public @interface TransactionalWithRollback {
}

そして、標準の@Transactionalの代わりにこのアノテーションを使用してください。

バリアント2:AnnotationTransactionAttributeSource から拡張機能を作成し、メソッドdetermineTransactionAttributeをオーバーライドできます:

protected TransactionAttribute  determineTransactionAttribute(AnnotatedElement ae)
//Determine the transaction attribute for the given method or class.

TransactionAttribute参照 TransactionAttribute api 、メソッドがあります

boolean rollbackOn(Throwable ex)指定された例外をロールバックする必要がありますか?

protected TransactionAttribute determineTransactionAttribute(
    AnnotatedElement ae) {
    return new DelegatingTransactionAttribute(target) {
        @Override
        public boolean rollbackOn(Throwable ex) {
           return (check is exception type as you need for rollback );
       }
};

}

2番目のアプローチは、トランザクションマネージャーにとって本当にグローバルであるため、最初のアプローチほど良くはありません。カスタムアノテーションは、本当に必要なメソッド/クラスにのみ適用するように制御できるため、より適切に使用してください。ただし、いずれにせよ2番目のバリアントを使用する必要がある場合は、デフォルトの国境を越えた動作になります。

9
xyz

この構成はそれを解決します:

@Configuration
public class MyProxyTransactionManagementConfiguration extends ProxyTransactionManagementConfiguration {

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource() {

            @Nullable
            protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
                TransactionAttribute ta = super.determineTransactionAttribute(element);
                if (ta == null) {
                    return null;
                } else {
                    return new DelegatingTransactionAttribute(ta) {
                        @Override
                        public boolean rollbackOn(Throwable ex) {
                            return super.rollbackOn(ex) || ex instanceof Exception;
                        }
                    };
                }
            }
        };
    }
}
3
DAN