Spring aop事务先后问题

         Spring中的事务是通过aop来实现的,当我们自己写aop拦截的时候,会遇到跟spring的事务aop执行的先后顺序问题,比如说动态切换数据源的问题,如果事务在前,数据源切换在后,会导致数据源切换失效,所以就用到了Order(排序)这个关键字.

        我们可以通过在@AspectJ的方法中实现org.springframework.core.Ordered 这个接口来定义order的顺序,order 的值越小,说明越先被执行。比如代码如下:

/**
 * @author HuifengWang
 * aop面向切面编程
 *
 */
@Component
@Aspect
public class AspectJ4DataBase implements Ordered{
     
    //拦截所有的service操作
    @Pointcut("execution( * com.hc.shop.*.service.*.*(..))")
    public void readMethod() {
    }// 匹配所有的读取操作
     
    @Before("readMethod()")
    public void onlyReadPre(){
        DataSourceContextHolder.setDataSourceType(DataSourceType.MYSQL);
        System.out.println("数据库切换MYSQL");
    }
    @After("readMethod()")
    public void onlyReadPast(){
        DataSourceContextHolder.setDataSourceType(DataSourceType.ORACLE);
        System.out.println("数据库切换回ORACLE");
    }
 
    @Override
    public int getOrder() {
        // TODO Auto-generated method stub
        return 1;
    }

 }

在事务配置的地方也配置order 字段,代码如下:
第一种配置:
<!-- 注解方式配置事物 -->
<tx:annotation-driven transaction-manager="transactionManager" order="2"/>

第二种配置:
<aop:aspectj-autoproxy proxy-target-class="true"/>
  <aop:config>
    <aop:pointcut id="appService"
      expression="execution(* com.zxxk.xybb.service..*.*(..))" />
    <!-- 注入通知 -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="appService" order="2"/>
  </aop:config>
  
  <!-- 定义事务通知 -->
  <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
      <tx:method name="select*" read-only="true" />
      <tx:method name="find*" read-only="true" />
      <tx:method name="get*" read-only="true" />
      <tx:method name="*" />
    </tx:attributes>
  </tx:advice>
  <!-- 定义事务管理器 -->
  <bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
  </bean>


你可能感兴趣的:(Spring aop事务先后问题)