当前位置:   article > 正文

spring嵌套事务,try-catch事务处理_try catch 事务

try catch 事务

spring 事务总结

前置条件

表Teacher 别名 A ,表Student 别名 B 分别插入。

A中启动事务,B中不启动事务 testDemo01调用方法开启事务

testDemo01开启事务,A中insert中开启事务,调用执行,A中执行成功,B中执行出现异常,AB事务回滚。
//A 表处理   
		@Override
    @Transactional
    public int insert(Teacher record) {

        log.info("teacher 插入开始....");
        return teacherDAO.insert(record);
    }
//B表处理
 		@Override
    public int insert(Student record) {
        log.info("Student 插入处理....");
        return studentDAO.insert(record);
    }
//调用方法处理
    @Transactional
    public void testDemo01() throws Exception{

        teacherService.insert(getTeacherEntity(2));
        studentService.insert(getStudentEntity(2));
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
A,B调用顺序调整。testDemo01开启事务,A中insert中开启事务,调用执行,A中执行异常,B中执行成功,AB事务回滚。
 @Transactional
    public void testDemo01() throws Exception{

        studentService.insert(getStudentEntity(2));
        teacherService.insert(getTeacherEntity(2));

    }
//A
@Override
    @Transactional
    public int insert(Teacher record) {

        log.info("teacher 插入开始....");
        int ss = teacherDAO.insert(record);
        int i = 1 / 0;
        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
A中事务开启新事务,调用后A调用异常,B中正常,A事务回滚,B事务不回滚
//A
@Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = teacherDAO.insert(record);
        int i = 1 / 0;
        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
A中开启事务,并使用try catch 将异常抓取。结果 A插入成功,B插入成功。事务没有执行会滚。
//调用方法
@Transactional
    public void testDemo01() throws Exception{

        studentService.insert(getStudentEntity(2));
        teacherService.insert(getTeacherEntity(2));

    }
//A
		@Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = 0;
        try{
            ss = teacherDAO.insert(record);
            int i = 1 / 0;
        }catch (Exception e){
            log.error(e.getMessage());
        }

        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
调用方法使用try catch 抓取异常。A方法正常抛出异常,事务进行了会滚,也就是student和teacher都进行了会滚。但是报 Transaction rolled back because it has been marked as rollback-only 异常,这个异常简单来讲,就是事务的传播机制导致的,teacher事务默认是用testDemo01调用方法的事务,但是teacher异常抛出的时候,teacher事务被标记成rollback 状态,所以,在调用方法testDemo01中即使使用trycatch捕捉了异常,同样也会做会滚,以为他俩使用的一个事务。
//调用方法
@Transactional
    public void testDemo01() throws Exception{

        try{
            studentService.insert(getStudentEntity(3));
            teacherService.insert(getTeacherEntity(3));
        }catch (Exception e){
            log.error(e.getMessage());
        }

    }
//Teacher方法
@Override
    @Transactional
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = teacherDAO.insert(record);
        int i = 1 / 0;
        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
调整teacher的事物传播机制为 (propagation = Propagation.REQUIRES_NEW),然后teacher会回滚,Student不会进行回滚。
 @Transactional
    public void testDemo01() throws Exception{

        try{
            studentService.insert(getStudentEntity(3));
            teacherService.insert(getTeacherEntity(3));
        }catch (Exception e){
            log.error(e.getMessage());
        }

    }
//
 @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = teacherDAO.insert(record);
        int i = 1 / 0;
        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
testDemo01方法和Teacher 都使用trycatch 处理,Teacher不抛出异常,testDemo01也不抛出异常,AB不回滚
 @Transactional
    public void testDemo01() throws Exception{

        try{
            studentService.insert(getStudentEntity(4));
            teacherService.insert(getTeacherEntity(3));
        }catch (Exception e){
            log.error(e.getMessage());
        }

    }
//
 @Override
    @Transactional
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = 0;
        try {
            ss = teacherDAO.insert(record);
            int i = 1 / 0;
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return ss;
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
testDemo01方法和Teacher 都使用trycatch 处理,Teacher修改事物隔离级别,不抛出异常,testDemo01也不抛出异常,AB不回滚
@Transactional
    public void testDemo01() throws Exception{

        try{
            studentService.insert(getStudentEntity(5));
            teacherService.insert(getTeacherEntity(4));
        }catch (Exception e){
            log.error(e.getMessage());
        }

    }
//
@Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = 0;
        try {
            ss = teacherDAO.insert(record);
            int i = 1 / 0;
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
testDemo01方法和Teacher 都使用trycatch 处理,Teacher抛出异常,testDemo01不抛出异常,AB不回滚
  @Transactional
    public void testDemo01() throws Exception{

        try{
            studentService.insert(getStudentEntity(6));
            teacherService.insert(getTeacherEntity(5));
        }catch (Exception e){
            log.error(e.getMessage());
        }

    }
// @Override
    @Transactional
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = 0;
        try {
            ss = teacherDAO.insert(record);
            int i = 1 / 0;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new Exception(e.getMessage());
        }

        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
testDemo01方法和Teacher 都使用trycatch 处理,Teacher抛出异常,testDemo01抛出异常(不指定那个异常回滚,注意异常要是RuntimeException,不能是其以上的异常,不然会会滚失败,或者指定异常会滚),AB回滚
  @Transactional
    public void testDemo01() throws Exception{

        try{
            studentService.insert(getStudentEntity(8));
            teacherService.insert(getTeacherEntity(7));
        }catch (Exception e){
            log.error(e.getMessage());
            throw new RuntimeException(e.getCause());
        }

    }
//或者指定会滚异常
 @Transactional(rollbackFor = {Exception.class})
    public void testDemo01() throws Exception{

        try{
            studentService.insert(getStudentEntity(8));
            teacherService.insert(getTeacherEntity(7));
        }catch (Exception e){
            log.error(e.getMessage());
            throw new Exception(e.getCause());
        }

    }
//
 @Override
    @Transactional
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = 0;
        try {
            ss = teacherDAO.insert(record);
            int i = 1 / 0;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new Exception(e.getMessage());
        }

        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
如果使用循环的方式处理异常,如何保证每次循环中 testDemo01中student和teacher 同时会滚,同时有不影响下次插入呢,就是,student每新增一条数据,teacher新增三条,他们的事务在一个事务中,每次执行一次遍历 ,AB都新增数据。然而在遍历中,某一次遍历出现异常后,AB都进行会滚,同时不影响上次遍历数据,不能中断遍历。解决办法是在调用方法时,首先要设立事务的传播特性修改成REQUIRES_NEW(开启新的事务,不在归调用者的事务管理,每次遍历的时候都会开启新事务),另外使用trycatch捕获异常后使用手动操作异常时会滚(这样就不会影响下次遍历了)。异常是否抛出对于调用者不影响。
@Transactional
    public void testC() throws Exception{

        for (int i = 1; i <4; i++) {
            try {
                testService.testDemo01(i);
            } catch (Exception e) {
                continue;
            }
        }
    }
//
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = {Exception.class})
    public void testDemo01(int i) throws Exception{

        try{
            studentService.insert(getStudentEntity(i));
            teacherService.insert(getTeacherEntity(i));
        }catch (Exception e){
            log.error(e.getMessage());
     		//手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new Exception(e.getCause());
        }

    }
//
  @Override
    @Transactional
    public int insert(Teacher record) throws Exception{

        log.info("teacher 插入开始....");
        int ss = 0;
        try {
            int k= record.getId();
            for (int i = 1; i < 3; i++) {

                if (k==1){
                    record.setId(1+i);
                }
                if (k==2){
                    record.setId(3+i);
                }
                if (k==3){
                    record.setId(6+i);
                }
                ss = teacherDAO.insert(record);

                if (k==2){
                    int t = 1 / 0;
                }
            }

        } catch (Exception e) {
            log.error(e.getMessage());
            throw new Exception(e.getMessage());
        }

        return ss;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/630190
推荐阅读
相关标签
  

闽ICP备14008679号