Spring Transaction Management:使用@Transactional与使用AOP(< aop:advisor) [英] Spring Transaction Management: using @Transactional vs using AOP (<aop:advisor)

查看:129
本文介绍了Spring Transaction Management:使用@Transactional与使用AOP(< aop:advisor)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Spring事务管理感到困惑。在我的应用程序中,我使用服务类中的@Transactional实现了事务管理。我配置我的spring.xml就像:

I have a confusion about Spring transaction management. In my application I implemented transaction management using @Transactional in the service class. And I configured my spring.xml is like:

    <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <beans:property name="dataSource" ref="dataSource" />
            <beans:property name="configLocation" value="classpath:hibernate.cfg.xml"/>                              
            <beans:property name="hibernateProperties">
                <beans:props>
                    <beans:prop key="hibernate.dialect">${jdbc.dialect}</beans:prop>
                    <beans:prop key="hibernate.show_sql">false</beans:prop>
                    <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
                </beans:props>
            </beans:property>
        </beans:bean>  
        <!-- Transaction manager -->
            <beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
                <beans:property name="sessionFactory" ref="sessionFactory" />
            </beans:bean> 

如果我在配置文件中实现事务管理,而不在服务类中使用@Transactional:

If I implement transaction management in the configuration file like below without using @Transactional in the service class:

    <aop:pointcut id="defaultServiceOperation"
            expression="execution(* x.y.service.*Service.*(..))"/>

    <aop:pointcut id="noTxServiceOperation"
            expression="execution(* x.y.service.ddl.DefaultDdlManager.*(..))"/>

    <aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>

    <aop:advisor pointcut-ref="noTxServiceOperation" advice-ref="noTxAdvice"/>

</aop:config>

它是否比@Transactional给我任何好处?有人告诉我使用@Transactional也是在春天实施AOP。谁能解释我怎么样?

does it give me any benefits over @Transactional? Someone told me using @Transactional is also implementation of AOP in spring. Can anyone explain me how?

推荐答案

它不会。

好处

如果您不需要某些非常规的要求或者没有性能问题,则不应重新发明轮子。 Spring几乎是完美设计,测试和锐化的仪器,甚至可以替代企业应用服务器。 @Transactional 是管理事务的声明方式,它比任何aop xml配置更方便和可读。它的好处包括以声明方式自动处理所有事务管理方面:隔离和传播级别(控制嵌套事务并不容易),超时,回滚条件以及服务类的每个方法的不同TransactionManagers。易于阅读,易于配置,易于使用。

If you don't need some very specified requirements or you have no performance issues, you shouldn't reinvent the wheel. Spring is almost perfectly designed, tested and sharped instrument, which can be replacement even for enterprise application servers. @Transactional is declarative way for managing transactions, it's far more convenient and readable than any aop xml configs. It's benefits include automatic handling of all transaction management aspects in declarative way: isolation and propagation levels (it's not easy to control nested transactions), timeouts, rollback conditions and distinct TransactionManagers for every single method of your service's class. Easy to read, easy to configure, easy to use.

@Transactional(readOnly = false, rollbackFor = ServiceException.class, isolation = Isolation.READ_COMMITTED)
public void myServiceJob(...)

当你看到这个方法,很容易理解它的事务属性(不在方法中提供事务实现细节)。如果你想知道这个方法会发生什么,那么你应该检查你的xml配置并找到相应的方法,这样就不那么优雅了。

When you see this method, it's easy to understand it's transactional attributes (without providing transactions implementation details in method). In case of plain AOP every time you want to know what happens in this method, you should check your xml config and find corresponding method, which is way less elegant.

On另一方面,调试或使用这些代理进行任何其他声明式管理非常困难。例如。它很棘手(但并非不可能)从上下文中提取你的bean并使用反射从你的被包装的bean中获取一些东西(比如说,用于监视目的)。另外,当bean调用其方法之一时,它不会被委托给代理,因为你的bean对代理一无所知,所以这个指的是bean本身。解决这个问题的唯一方法是提供自我字段并将其设置在自定义bean后处理器中(但是你的实现也受此影响)。

On other hand, it's very hard to debug or use these proxies for any other declarative management. E.g. it's tricky (but not impossible) extract your bean from context and get something out of your wrapped bean using reflection (let's say, for monitoring purposes). In addition, when bean calls one of its method, it won't be delegated to proxy, because your bean knows nothing about proxy, so this refers to bean itself. The only way to cure this it to provide "self" field and set it in custom bean postprocessor (but your implementation suffers from this either).

实现

如果Spring配置为使用事务管理,那么它正在寻找关于bean定义的 @Transactional 注释创建自动生成的AOP代理,它是bean的子类。 Spring代理的默认行为就是将方法的调用委托给底层bean。然后Spring向TransactionInterceptor注入必要的TransactionManagers。
拦截器代码看起来很简单:

If Spring is configured to use transactional management, it's looking for @Transactional annotation on bean's definitions and creates auto-generated AOP proxy, which is subclass of your bean. Default behavior of Spring proxy is just delegating method's calls to underlying bean. Then Spring injects TransactionInterceptor with necessary TransactionManagers. Code of interceptor looks quite simple:

public Object invoke(final MethodInvocation invocation) throws Throwable {
    // Work out the target class: may be {@code null}.
    // The TransactionAttributeSource should be passed the target class
    // as well as the method, which may be from an interface.
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

    // Adapt to TransactionAspectSupport's invokeWithinTransaction...
    return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
        @Override
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
    });
}

内部invokeWithinTransaction TransactionInterceptor确定调用是在调用者事务(如果存在)的范围内还是在新调用事务的范围内(它与传播级别有关)。然后选择相应的TransactionManager,配置超时和隔离级别,然后调用该方法。在它决定是否应该提交或回滚事务之后(根据捕获的异常和时间选择)。

Inside of invokeWithinTransaction TransactionInterceptor determines whether should invocation be in scope of caller transaction (if one exists) or in a new one (it's about propagation level). Then it choses corresponding TransactionManager, configures timeout and isolation level, then invokes the method. After it decides if transaction should be commited or rolled back (choice is made based on caught exception and timing).

这篇关于Spring Transaction Management:使用@Transactional与使用AOP(&lt; aop:advisor)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆