回滚每个选中的异常,每当我说@Transactional

2022-09-01 04:59:52

由于程序员被迫捕获所有已检查的异常,因此在出现任何问题时,我将抛出已检查的异常。我想回滚任何这些期望。在每一个注释上写字都非常容易出错,所以我想告诉春天,“每当我写的时候,我的意思是”。rollbackFor=Exception.class@Transactional@Transactional@Transactional(rollbackFor=Exception.class)

我知道,我可以创建自定义注释,但这似乎不自然。

那么,有没有办法告诉春天它应该如何处理全球检查的豁免?


答案 1

自定义快捷键批注

我知道,我可以创建自定义注释,但这似乎不自然。

不,这正是自定义注释的用例。以下是《春季参考》中“自定义快捷键注释”中的一句话:

如果您发现自己在许多不同的方法上反复使用相同的属性和@Transactional,那么Spring的元注释支持允许您为特定用例定义自定义快捷方式注释。

示例代码

下面是您的用例的示例注释:

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

现在用注释你的服务和/或方法(你会想到一个更好的名字)。这是经过充分测试的功能,默认情况下可以正常工作。为什么要重新发明轮子?@MyAnnotation


答案 2

使用自定义注释的方法看起来不错且简单明了,但是如果您实际上不想使用它,则可以创建自定义来修改以下解释:TransactionAttributeSource@Transactional

public class RollbackForAllAnnotationTransactionAttributeSource 
    extends AnnotationTransactionAttributeSource {
    @Override
    protected TransactionAttribute determineTransactionAttribute(
            AnnotatedElement ae) {
        TransactionAttribute target = super.determineTransactionAttribute(ae);
        if (target == null) return null;
        else return new DelegatingTransactionAttribute(target) {
            @Override
            public boolean rollbackOn(Throwable ex) {
                return true;
            }
        };
    }
}

而不是按如下方式手动配置它(请参阅源代码):<tx:annotation-driven/>AnnotationDrivenBeanDefinitionParser

<bean id = "txAttributeSource"
    class = "RollbackForAllAnnotationTransactionAttributeSource" />

<bean id = "txInterceptor"
    class = "org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name = "transactionManagerBeanName" value = "transactionManager" />
    <property name = "transactionAttributeSource" ref = "txAttributeSource" />
</bean>

<bean
    class = "org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor">
    <property name="transactionAttributeSource" ref = "txAttributeSource" />
    <property name = "adviceBeanName" value = "txInterceptor" />
</bean>

您还需要 或 .<aop:config/><aop:aspectj-autoproxy />

但是请注意,对于期望正常行为为 的其他开发人员来说,此类覆盖可能会令人困惑。@Transactional


推荐