初学者,参照别人的经验,配置文件如下 <!-- 配置切面 -->
 <aop:config proxy-target-class="true" >
  <aop:pointcut id="servicePointcut" expression="execution(* com.orm.hr.dao.*.*(..))" />
  <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut" />
 </aop:config>
 <tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
   <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
   <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
   <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
   <tx:method name="*" read-only="true"/>
  </tx:attributes>
 </tx:advice>
这样的话,运行正常没有问题,事务都能提交,但是,这样切面是在dao层,一些涉及到多个crud操作的service层的方法就不好处理。我想把切面放在service层,应该怎么做?我尝试直接修改execution为(* com.orm.hr.service.*.*(..)),也能运行,但是事务不提交。

解决方案 »

  1.   

    execution(* com.orm.hr.dao.*.*(..)):表示管理com.orm.hr.dao下所有子类,所有子类方法* com.orm.hr.service.*.*(..):表示管理com.orm.hr.service下所有子类,所有子类方法我尝试直接修改execution为(* com.orm.hr.service.*.*(..)),也能运行?程序怎么写的
      

  2.   


    com.orm.hr.service包下面就一个类EmployeeService,这个类就一个方法login
    public Employee login(String username, String password, int departmentId) throws LoginException{
    Employee employee = this.employeeDao.getEmployeeByLogin(username, password);
    if(employee == null){
    throw new LoginException("工号或密码错误。");
    }else{
    if(employee.getDepartment().getId() != departmentId){
    throw new LoginException("该工号不在所选择的部门。");
    }else{
            employee.setLoginCount(employee.getLoginCount() + 1);
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(System.currentTimeMillis());
            employee.setLoginTime(c);
    this.employeeDao.updateEmployee(employee);
            return employee;
    }
    }
      

  3.   

    tx advice也已经改成了 <tx:advice id="txAdvice" transaction-manager="transactionManager">
      <tx:attributes>
       <tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
      </tx:attributes>
     </tx:advice>
      

  4.   

    每个Dao层的操作都涉及一个事务,因此,当切面设置在Service层的时候,就需要处理事务边界的问题,事务边界不能再由具体的原子(DAO层操作)来负责,而是应该托管给容器,因此可以抽象一个AOP切面专门负责Service层的事务切入,然后简化掉所有的DAO层的事务,并关闭ORM或JDBC中的事务自动提交。
      

  5.   

    楼主可以参看以下这篇文章,其中涉及在Spring中借助AOP来托管事务的一些方法,另外,这篇文章也提供了有另外一种解决思路,可以用在不同的配置模式下。
      

  6.   

    http://topic.csdn.net/u/20100120/17/5ca75ab5-7278-42d0-888b-d0157b74ad71.html
    http://hi.baidu.com/freshman0502/blog/item/8068e01b5038d01c8618bf8e.html
      

  7.   

     试一试把 execution(* com.orm.hr.dao.*.*(..))
      改成
            *  execution(* com.orm.hr.dao.*.*(..))
       表示任意方法的任意返回值
      

  8.   

    AOP和Spring事务处理  http://www.phome.asia/forum/thread/17913.html
      

  9.   

    Spring结合Hibernate声明式事务配置  http://www.phome.asia/forum/thread/18065.html
      

  10.   

    修改execution为(* com.orm.hr.service.*.*(..))是正确的,

    <tx:attributes>
       <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
       <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
       <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
       <tx:method name="*" read-only="true"/>
      </tx:attributes>
    里面<tx:method name="*" read-only="true"/>
    配置前加一个
    <tx:method name="login*" propagation="REQUIRED" rollback-for="Exception"/>
    如果不加这个的话login方法为只读的,所以你不能修改数据,事物没提交了
    <tx:attributes>
       <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
       <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
       <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
       <tx:method name="login*" propagation="REQUIRED" rollback-for="Exception"/>
       <tx:method name="*" read-only="true"/>
     </tx:attributes>