Spring中事务嵌套:Transaction rolled back because it has been marked as rollback-only 异常处理

Springboot中事务嵌套:Transaction rolled back because it has been marked as rollback-only 异常处理

1.实验基本介绍

两个方法A、B,分别属于不同的类,其中A方法循环调用B方法,基础结构如下:

    /**
     * A方法
     */
@Override
public void testAll() {
    CmsContent cmsContent = new CmsContent();
    cmsContent.setTitle("SSS");
    cmsContentMapper.insertCmsContent(cmsContent);
    for (int i = 0; i < 10; i++) {
        try {
            categoryService.test(i);
        } catch (Exception e) {
            System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
        }
    }
}
    /**
     * B方法
     */
public void test(int i) {

    CmsCategory cmsCategory = new CmsCategory();
    cmsCategory.setCategoryName("SSS" + i);
    cmsCategory.setAlias(i+"ss");
    cmsCategoryMapper.insertCmsCategory(cmsCategory);
    if (i == 4) {
        System.out.println(1 / 0);
    }
}
     /**
     * 测试方法
     */
  @org.junit.Test
    public void testParse() {
        try {
            cmsContentService.testAll();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.println("-------------------");
        }

2.实验过程

2.1 A方法加事务,B方法不加事务,同时A方法捕获B方法的异常,那么此时的结果:

-------A和B都不回滚----

    /**
     * A方法
     */
@Transactional(rollbackFor = Exception.class)
@Override
public void testAll() {
    CmsContent cmsContent = new CmsContent();
    cmsContent.setTitle("SSS");
    cmsContentMapper.insertCmsContent(cmsContent);
    for (int i = 0; i < 10; i++) {
        try {
            categoryService.test(i);
        } catch (Exception e) {
            System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
        }
    }
}
    /**
     * B方法
     */
public void test(int i) {

    CmsCategory cmsCategory = new CmsCategory();
    cmsCategory.setCategoryName("SSS" + i);
    cmsCategory.setAlias(i+"ss");
    cmsCategoryMapper.insertCmsCategory(cmsCategory);
    if (i == 4) {
        System.out.println(1 / 0);
    }
}

2.2 A方法加事务,B方法不加事务,A方法捕获B方法的异常,并且在捕获异常时,将当前事务的回滚状态变成true,(TransactionAspectSupport.currentTransactionStatus().setRollbackOnly())那么此时的结果:-------A回滚,----B全部都回滚

@Transactional(rollbackFor = Exception.class)
@Override
public void testAll() {
    CmsContent cmsContent = new CmsContent();
    cmsContent.setTitle("SSS");
    cmsContentMapper.insertCmsContent(cmsContent);
    for (int i = 0; i < 10; i++) {
        try {
            categoryService.test(i);
        } catch (Exception e) {
            System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
}
@Override
public void test(int i) {

    CmsCategory cmsCategory = new CmsCategory();
    cmsCategory.setCategoryName("SSS" + i);
    cmsCategory.setAlias(i+"ss");
    cmsCategoryMapper.insertCmsCategory(cmsCategory);
    if (i == 4) {
        System.out.println(1 / 0);
    }
}

2.3 A方法加事务,B方法加事务,同时A方法捕获B方法的异常,那么此时的结果:

— A回滚,B全部都回滚,但是调用的A的测试方法抛出异常:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

   @Transactional(rollbackFor = Exception.class)
    @Override
    public void testAll() {
        CmsContent cmsContent = new CmsContent();
        cmsContent.setTitle("SSS");
        cmsContentMapper.insertCmsContent(cmsContent);
        for (int i = 0; i < 10; i++) {
            try {
                categoryService.test(i);
            } catch (Exception e) {
                System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
            }
        }
    }
@Transactional(rollbackFor = Exception.class)
@Override
public void test(int i) {

    CmsCategory cmsCategory = new CmsCategory();
    cmsCategory.setCategoryName("SSS" + i);
    cmsCategory.setAlias(i+"ss");
    cmsCategoryMapper.insertCmsCategory(cmsCategory);
    if (i == 4) {
        System.out.println(1 / 0);
    }
}

2. 4 .A方法加事务,B方法加事务,同时A方法捕获B方法的异常,A方法捕获B方法的异常,并且在捕获异常时,将当前事务的回滚状态变成true,(TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()),那么此时的结果:----A,B全部都回滚,但是调用的A的测试方法没有抛出异常

@Transactional(rollbackFor = Exception.class)
@Override
public void testAll() {
    CmsContent cmsContent = new CmsContent();
    cmsContent.setTitle("SSS");
    cmsContentMapper.insertCmsContent(cmsContent);
    for (int i = 0; i < 10; i++) {
        try {
            categoryService.test(i);
        } catch (Exception e) {
            System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
}
@Transactional(rollbackFor = Exception.class)
@Override
public void test(int i) {

    CmsCategory cmsCategory = new CmsCategory();
    cmsCategory.setCategoryName("SSS" + i);
    cmsCategory.setAlias(i+"ss");
    cmsCategoryMapper.insertCmsCategory(cmsCategory);
    if (i == 4) {
        System.out.println(1 / 0);
    }
}

2. 5 A方法加事务,B方法加事务,同时B的事务是一个新事务(Propagation.REQUIRES_NEW),同时A方法捕获B方法的异常,那么此时的结果:

-----A不回滚,B单条回滚,并且调用的A的测试方法没有抛出异常

  @Transactional(rollbackFor = Exception.class)
    @Override
    public void testAll() {
        CmsContent cmsContent = new CmsContent();
        cmsContent.setTitle("SSS");
        cmsContentMapper.insertCmsContent(cmsContent);
        for (int i = 0; i < 10; i++) {
            try {
                categoryService.test(i);
            } catch (Exception e) {
                System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
            }
        }
    }
  @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    @Override
    public void test(int i) {

        CmsCategory cmsCategory = new CmsCategory();
        cmsCategory.setCategoryName("SSS" + i);
        cmsCategory.setAlias(i+"ss");
        cmsCategoryMapper.insertCmsCategory(cmsCategory);
        if (i == 4) {
            System.out.println(1 / 0);
        }
    }

2. 6 A方法加事务,B方法加事务,同时B的事务是一个新事务(Propagation.REQUIRES_NEW),同时A方法捕获B方法的异常,并且在捕获异常时,将当前事务的回滚状态变成true(TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()),那么此时的结果:----A回滚,B单条回滚,并且调用的A的测试方法没有抛出异常

@Transactional(rollbackFor = Exception.class)
@Override
public void testAll() {
    CmsContent cmsContent = new CmsContent();
    cmsContent.setTitle("SSS");
    cmsContentMapper.insertCmsContent(cmsContent);
    for (int i = 0; i < 10; i++) {
        try {
            categoryService.test(i);
        } catch (Exception e) {
            System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
}
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
@Override
public void test(int i) {

    CmsCategory cmsCategory = new CmsCategory();
    cmsCategory.setCategoryName("SSS" + i);
    cmsCategory.setAlias(i+"ss");
    cmsCategoryMapper.insertCmsCategory(cmsCategory);
    if (i == 4) {
        System.out.println(1 / 0);
    }
}

2. 7 A方法加事务,没有异常抛出,但是最后将当前事务的回滚状态变成true(TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()),,那么此时的结果:—A回滚

  @Transactional(rollbackFor = Exception.class)
    @Override
    public void testAll() {
        CmsContent cmsContent = new CmsContent();
        cmsContent.setTitle("SSS");
        cmsContentMapper.insertCmsContent(cmsContent);
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }

即:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()的作用是让当前事务回滚。

2.8 A方法不添加事务,B方法加事务,同时A方法捕获B方法的异常,那么此时的结果:

— A不回滚,B单条回滚

    @Override
    public void testAll() {
        CmsContent cmsContent = new CmsContent();
        cmsContent.setTitle("SSS");
        cmsContentMapper.insertCmsContent(cmsContent);
        for (int i = 0; i < 10; i++) {
            try {
                categoryService.test(i);
            } catch (Exception e) {
                System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
            }
        }
    }
@Transactional(rollbackFor = Exception.class)
@Override
public void test(int i) {

    CmsCategory cmsCategory = new CmsCategory();
    cmsCategory.setCategoryName("SSS" + i);
    cmsCategory.setAlias(i+"ss");
    cmsCategoryMapper.insertCmsCategory(cmsCategory);
    if (i == 4) {
        System.out.println(1 / 0);
    }
}

2.9 A方法不添加事务,B方法加事务,同时B的事务是一个新事务(Propagation.REQUIRES_NEW),A方法捕获B方法的异常,那么此时的结果:

— A不回滚,B单条回滚

    @Override
    public void testAll() {
        CmsContent cmsContent = new CmsContent();
        cmsContent.setTitle("SSS");
        cmsContentMapper.insertCmsContent(cmsContent);
        for (int i = 0; i < 10; i++) {
            try {
                categoryService.test(i);
            } catch (Exception e) {
                System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
            }
        }
    }
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    @Override
    public void test(int i) {

        CmsCategory cmsCategory = new CmsCategory();
        cmsCategory.setCategoryName("SSS" + i);
        cmsCategory.setAlias(i+"ss");
        cmsCategoryMapper.insertCmsCategory(cmsCategory);
        if (i == 4) {
            System.out.println(1 / 0);
        }
    }

2. 10 A方法不加事务,B方法加事务,同时B的事务是一个新事务(Propagation.REQUIRES_NEW),A方法捕获B方法的异常,并且在捕获异常时,将当前事务的回滚状态变成true(TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()),那么此时的结果:----A不回滚,B只执行前4条,并且前四条数据不回滚,并且调用的A的测试方法会抛出异常:No transaction aspect-managed TransactionStatus in scope。也就是A方法没有事务存在。

    @Override
    public void testAll() {
        CmsContent cmsContent = new CmsContent();
        cmsContent.setTitle("SSS");
        cmsContentMapper.insertCmsContent(cmsContent);
        for (int i = 0; i < 10; i++) {
            try {
                categoryService.test(i);
            } catch (Exception e) {
                System.out.println("testAlltestAlltestAlltestAll:" + e.getMessage());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }
    }
     @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    @Override
    public void test(int i) {

        CmsCategory cmsCategory = new CmsCategory();
        cmsCategory.setCategoryName("SSS" + i);
        cmsCategory.setAlias(i+"ss");
        cmsCategoryMapper.insertCmsCategory(cmsCategory);
        if (i == 4) {
            System.out.println(1 / 0);
        }
    }

以上就是这事务嵌套的各种情况。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值