日期:2014-05-19  浏览次数:20769 次

spring aop管理事务的一个疑问
一般事务都是配置在service层的,现在我有一个情况
比如:用户更改密码后要调用保存一个日志
public void changePassword(User user)throws Exception{
    userDao.update(user);//更改密码
    logService.saveLog(log);//保存日志
}
--------------------------
使用aop控制事务时,会在logService中的所有方法加上事务边界,同理,会在
userService中的指定方法也加上事务边界,那如果我在保存日志的过程中抛出
了异常,这时候 userDao.update(user);方法已执行并提交了。那这样说来,
service与service之间就无法事务同步了?

------解决方案--------------------
你的spring事务隔离级别是不是没有控制好?默认的隔离级别是这个
@Transactional(propagation=Propagation.REQUIRED) //如果有事务,那么加入事务,没有的话新建一个(不写的情况下) 
@Transactional 的事务开启 ,或者是基于接口的 或者是基于类的代理被创建。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的。
照楼主所说应该改成如下:
@Transactional(propagation=Propagation.REQUIRES_NEW) //不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务   

对spring事务的隔离级别,楼主还需要多阅读文档,你的问题一定是这个原因导致的.
------解决方案--------------------
事务都是配置在service层的这个没错
所以你的数据库的操作应该写在一个service方法里
以你的情况
可以在userService里注入logService,然后在一个service里调用logService的方法即可
------解决方案--------------------
如果说是因为userDao.update(user);方法已执行并提交了导致changePassword方法无法按事务运行, 那即使saveLog不是事务的,changePassword还不是照样不能够实现事务?
------解决方案--------------------
主要看你的事务是怎么配置的,如果你的DAO层的执行成功就会提交事务,那么你那个方法是没办法实现日志错误导致用户修改信息回退的
------解决方案--------------------
事务隔离级别设置成Required,userDao.update()是可以回滚的
------解决方案--------------------
当然,也可以看一下数据库。我之前用mysql的时候,使用的是root权限。结果就是日志里面已经说明回滚了。但是数据库里面依然没有回滚。