spring事物–代理的影响

版权声明:欢迎转载,标明出处 https://blog.csdn.net/mz4138/article/details/82668463

spring事物–代理的影响

本文章只讨论spring代理在事物中的影响。 列举出常见的事物失效的情况,以及如何处理

不是对spring事物传播机制的说明

接下来按两种方式讨论对事物的影响
1. 主方法被事物管理,包含事物方法
2. 主方法不被事物管理,包含事物方法

默认数据

id title
1 title1
2 title2

事务方法

普通提交与回滚

对于声明式事务的简单介绍

成功提交

    @Transactional
    public void normalCommit(){
        Blog blogA = new Blog();
        blogA.setId(1);
        blogA.setTitle("normalCommit");
        blogMapper.update(blogA);
    }
id title
1 normalCommit
2 title2

回滚

    @Transactional
    public void normalCommit(){
          Blog blogA = new Blog();
          blogA.setId(1);
          blogA.setTitle("normalRollback");
          blogMapper.update(blogA);

         throw new RuntimeException("rollback exception");
    }
id title
1 title1
2 title2

本地方法加入事物

加入回滚事物,事物回滚成功

    @Transactional
    @Override
    public void normalGroup(){
        normalRollback();
    }

spring回滚边界

spring 事务管理器 默认回滚RuntimeException及其子类异常,如果不是则需要手动扩大回滚异常范围

不回滚

@Override
    @Transactional
    public void exceptionNotRollback() throws Exception {
        Blog blogA = new Blog();
        blogA.setId(1);
        blogA.setTitle("exceptionNotRollback");
        blogMapper.update(blogA);


        throw new Exception("exception not rollback");
    }
id title
1 exceptionNotRollback
2 title2

回滚

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void exceptionRollback() throws Exception {
        Blog blogA = new Blog();
        blogA.setId(1);
        blogA.setTitle("exceptionRollback");
        blogMapper.update(blogA);


        throw new Exception("exception not rollback");
    }
id title
1 title1
2 title2

回滚部分内容

吃掉异常-全部提交

    @Transactional
    @Override
    public void eatException() {
        Blog blogA = new Blog();
        blogA.setId(1);
        blogA.setTitle("eat exception");
        blogMapper.update(blogA);

        // 吃掉异常,提交所有事务
        try {
            normalRoolbackB();
        } catch (Exception e) {

        }

    }

    @Transactional
    public void normalRoolbackB() {
        Blog blogA = new Blog();
        blogA.setId(2);
        blogA.setTitle("normalRoolbackB");
        blogMapper.update(blogA);

        throw new RuntimeException("rollback some local transaction");
    }

数据内容:

id title
1 eat exception
2 normalRoolbackB

虽然出现了异常,但是没有回滚,而是全部提交

吃掉异常-回滚异常内容

    @Transactional
    @Override
    public void notEatException() {
        Blog blogA = new Blog();
        blogA.setId(1);
        blogA.setTitle("not eat exception");
        blogMapper.update(blogA);

        try {
        // 开启事物
            BlogTxServiceImpl blogTxService = (BlogTxServiceImpl) AopContext.currentProxy();
            blogTxService.normalRoolbackB();
        } catch (Exception e) {
            // 吃掉异常,提交所有事务
        }
    }

通过AopContext.currentProxy()获得当前代理对象,开启一个新的事物。

id title
1 not eat exception
2 title2

非事务方法

公共调用方法:

    //修改id=2的记录的title,然后抛出异常
    @Transactional
    public void normalRoolbackB() {
        Blog blogA = new Blog();
        blogA.setId(2);
        blogA.setTitle("normalRoolbackB");
        blogMapper.update(blogA);

        throw new RuntimeException("rollback some local transaction");
    }

包含事物方法-失效

    @Override
    public void notTxSimple() {
        normalRoolbackB();
    }

包含了事物,但是却没有效果。 这是用spring事物最容易迷惑的地方

id title
1 title1
2 normalRoolbackB

包含事物方法-代理事物

    @Override
    public void notTxSimpleToSimple() {
        BlogTxServiceImpl blogTxService = (BlogTxServiceImpl) AopContext.currentProxy();
        blogTxService.normalRoolbackB();
    }

获得代理事物,在非事物方法中开启事物

事物生效,回滚了数据

id title
1 title1
2 title2

总结

  1. 默认不会滚异常: RuntimeException 以及子类异常
  2. 本类调用时,开启独立事物需要用AopContext.currentProxy()获得当前代理对象,然后再去执行操作

猜你喜欢

转载自blog.csdn.net/mz4138/article/details/82668463