Spring Transaction Management:使用@Transactional与使用AOP(<aop:advisor)

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

     ${jdbc.dialect} false update        

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

       

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

它不会。

优点

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

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

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

另一方面,调试或使用这些代理进行任何其他声明性管理非常困难。 例如,它很棘手(但并非不可能)从上下文中提取bean并使用reflection从包装bean中获取一些东西(比如说,用于监视目的)。 此外,当bean调用其方法之一时,它不会被委托给代理,因为你的bean对代理一无所知,所以this指的是bean本身。 解决此问题的唯一方法是提供“self”字段并将其设置在自定义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,配置超时和隔离级别,然后调用该方法。 在它决定是否应该提交或回滚事务之后(根据捕获的exception和时间选择)。