由于程序员被强制捕获所有已检查的异常,因此我会在出现任何问题时抛出已检查的异常。我想回滚任何这些期望。在每个rollbackFor=Exception.class
注释上写@Transactional
非常容易出错,所以我想告诉春天:“每当我写@Transactional
时,我的意思是@Transactional(rollbackFor=Exception.class)
”。< / p>
我知道,我可以创建一个自定义注释,但这似乎不自然。
那么有没有办法告诉spring它应该如何处理全局全局检查的删除?
答案 0 :(得分:52)
我知道,我可以创建一个自定义 注释,但这似乎不自然。
不,这正是自定义注释的用例。以下是Spring Reference中Custom Shortcut Annotations的引用:
如果您发现您反复使用 与...相同的属性 @Transactional对很多不同 方法,然后是Spring的元注释 支持允许您定义自定义 特定的快捷方式注释 用例。
这是一个用例的示例注释:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(rollbackFor=Exception.class)
public @interface MyAnnotation {
}
现在使用@MyAnnotation
注释您的服务和/或方法(您会想到一个更好的名字)。这是经过良好测试的功能,默认情况下有效。为什么重新发明轮子?
答案 1 :(得分: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;
}
};
}
}
而不是<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
的正常行为的其他开发者而言,此类覆盖可能会造成混淆。
答案 2 :(得分:3)
你可以:
throw new RuntimeException(checkedException)
MethodInterceptor
(或@AroundInvoke
或其他任何方式在spring中创建方面),通过指定{来声明它在<tx:annotation-driven />
之前执行{1}}和order="1"
并抓住并包裹在那里。答案 3 :(得分:3)
看起来您可以根据方法名称配置事务建议,如下所示: (来自the Spring 2.0 docs)
可以配置哪种异常类型标记回滚事务。在下面找到一个XML配置片段,演示如何为已检查的,特定于应用程序的Exception类型配置回滚。
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="false" rollback-for="NoProductInStockException"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>