Spring Transaction Management:使用@Transactional与使用AOP(

时间:2015-03-24 17:35:12

标签: java spring aop spring-transactions

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

    <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:

    <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。谁能解释我怎么样?

1 个答案:

答案 0 :(得分:0)

它赢了。

好处

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

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

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

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

<强>实施

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

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,配置超时和隔离级别,然后调用该方法。在它决定是否应该提交或回滚事务之后(根据捕获的异常和时间选择)。