二十二、spring 事务之踩过的坑

这节主要记录我在使用Spring事务过程中遇到过的坑。

没有抛出异常

@Transactional
public void addUser(User user) {
    try {
        userMapper.addUser(user);
        int i = 1/0;
    } catch (Exception e) {
        e.printStackTrace();
    }
}

上面代码user是能够添加成功的,因为不抛出异常,spring是没有办法捕获的,所以就不能执行回滚。

this调用声明REQUIRES_NEW的事务,是不会重新创建事务的

@Transactional
public void addUser(User user) {
    this.update();
}

@Transactional(propagation = REQUIRES_NEW)
public void update() {

}

update()方法不会重新创建一个事务的,因为this指向的是目标方法,而要使用事务必须使用代理对象才能生效。为了解决这个问题,可以通过下面方式:

@EnableAspectJAutoProxy(exposeProxy = true)

然后将this.update()修改为:

((UserService)AopContext.currentProxy()).update();

AopContext.currentProxy()是在创建代理的时候,通过下面代码赋值的

if (this.advised.exposeProxy) {
    // Make invocation available if necessary.
    oldProxy = AopContext.setCurrentProxy(proxy);
    setProxyContext = true;
}

Transaction rolled back because it has been marked as rollback-only异常

这个是一个同事问我,他想做的是在a方法中调用b方法,但是b失败,不影响a的事务,代码如下:

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private EmployeeService employeeService;

    @Transactional
    public void addUser(User user) {
        userMapper.addUser(user);
        try {
            employeeService.addEmployee();
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }
}
@Service
public class EmployeeService {

    @Transactional
    public void addEmployee() {
        int i = 1/0;
    }
}

这个是因为在addEmployee中抛出异常时,在回滚时如果不是一个新的事务就会把事务状态设置成readOnly,但是在addUser中又没有把异常抛出,所以会提交事务,在提交的时候就会校验事务是否设置成readOnly,就抛出UnexpectedRollbackException异常。解决办法就是让addEmployee新启一个事务@Transactional(propagation = Propagation.REQUIRES_NEW)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,246评论 19 139
  • 不足的地方请大家多多指正,如有其它没有想到的常问面试题请大家多多评论,一起成长,感谢!~ String可以被继承吗...
    启示录是真的阅读 3,009评论 3 3
  • 很多人喜欢这篇文章,特此同步过来 由浅入深谈论spring事务 前言 这篇其实也要归纳到《常识》系列中,但这重点又...
    码农戏码阅读 4,803评论 2 59
  • Spring 事务属性分析 事务管理对于企业应用而言至关重要。它保证了用户的每一次操作都是可靠的,即便出现了异常的...
    壹点零阅读 1,337评论 0 2
  • 是时候考虑一波未来了。 2016.2.1
    将去君阅读 156评论 0 0