Spring:对已检查的异常进行自动回滚

sar*_*ara 11 java spring transactional

配置Spring以对非回滚的一种方法RuntimeExceptions@Transactional(rollbackFor=...)在服务类上使用注释.这种方法的问题是我们需要为几乎所有似乎真正冗余的服务类定义(rollbackFor = ...).


我的问题:有没有办法为Spring事务管理器配置默认行为,以便在非RuntimeException事件发生时回滚而不在每个@Transactional注释上声明它.类似于@ApplicationException(rollback=true)在EJB中的异常类上使用注释.

DAN*_*DAN 11

这个配置解决了它:

@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;
                        }
                    };
                }
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)


xyz*_*xyz 9

使用@Transactional不能用于应用程序级别,但您可以:

变体1:扩展@Transactional注释并将其作为rollbackfor的默认值.但是只设置你需要的rollbackFor unchecked异常.这样你就可以控制回滚只针对你确定的情况,并避免复制过去@Transactional(rollbackFor = MyCheckedException.class)

喜欢:

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

并使用此注释而不是标准的@Transactional.

变体2:您可以从AnnotationTransactionAttributeSource创建扩展并覆盖方法determineTransactionAttribute:

protected TransactionAttribute  determineTransactionAttribute(AnnotatedElement ae)
//Determine the transaction attribute for the given method or class.
Run Code Online (Sandbox Code Playgroud)

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 );
       }
};
Run Code Online (Sandbox Code Playgroud)

}

第二种方法并不像第一种方法那样好,因为对事务管理器来说它实际上是全局的.更好地使用自定义注释,因为您可以控制它只适用于您真正需要它的方法/类.但如果您在任何情况下都需要使用第二种变体,那么它将是您的默认跨国行为.