每当我说@Transactional时,回滚每个检查过的异常

pih*_*agy 36 java spring jpa jpa-2.0

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

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

那么有没有办法告诉spring它应该如何处理全局检查的删除?

Sea*_*oyd 56

自定义快捷方式注释

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

不,这正是自定义注释的用例.以下是Spring Reference中Custom Shortcut Annotations的引用:

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

示例代码

这是一个用例的示例注释:

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

现在用@MyAnnotation(你会想到一个更好的名字)注释你的服务和/或方法.这是经过良好测试的功能,默认情况下有效.为什么重新发明轮子?


axt*_*avt 15

使用自定义注释的方法看起来很好而且直截了当,但如果您实际上不想使用它,则可以创建自定义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;
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

而不是<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>
Run Code Online (Sandbox Code Playgroud)

你也需要<aop:config/><aop:aspectj-autoproxy />.

但请注意,对于期望正常行为的其他开发人员而言,此类覆盖可能会造成混淆@Transactional.