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
.