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