Since the programmer is forced to catch all checked exception, I to throw checked exception in case of any problem. I would like to rollback on any of those expections. Writing rollbackFor=Exception.classon every @Transactional annotation is very erro开发者_开发问答r-prone, so I would like to tell spring, that: "whenever I write @Transactional, I mean @Transactional(rollbackFor=Exception.class)".
I know, that I could create a custom annotation, but that seems unnatural.
So is there a way to tell spring how it should handle checked excpetions globally?
Custom Shortcut Annotations
I know, that I could create a custom annotation, but that seems unnatural.
No, this is exactly the use case for a Custom Annotation. Here's a quote from Custom Shortcut Annotations in the Spring Reference:
If you find you are repeatedly using the same attributes with @Transactional on many different methods, then Spring's meta-annotation support allows you to define custom shortcut annotations for your specific use cases.
Sample Code
And here's a sample annotation for your use case:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(rollbackFor=Exception.class)
public @interface MyAnnotation {
}
Now annotate your services and / or methods with @MyAnnotation (you'll think of a better name). This is well-tested functionality that works by default. Why re-invent the wheel?
Approach with custom annotation looks good and straightforward, but if you actually don't want to use it, you can create a custom TransactionAttributeSource to modify interpretation of @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;
            }
        };
    }
}
And instead of <tx:annotation-driven/> you configure it manually as follows (see source of 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>
Also you need <aop:config/> or <aop:aspectj-autoproxy />.
However note that such overrides may be confusing for other developers who expect a normal behaviour of @Transactional.
You can:
- catch and wrap the checked exception into an unchecked exception - throw new RuntimeException(checkedException)
- create a proxy around the method, using MethodInterceptor(or@AroundInvoke, or any other means to create aspects in spring), declare it to be executed before the<tx:annotation-driven />by specifyingorder="1"andorder="2"and catch and wrap there.
Looks like you can configure a transactional advice based on method name like this: (from the Spring 2.0 docs)
Exactly which Exception types mark a transaction for rollback can be configured. Find below a snippet of XML configuration that demonstrates how one would configure rollback for a checked, application-specific Exception type.
<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>
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论