Spring事务传播机制详解和 @Transactional 失效情况原因及解决方法(IT枫斗者)

本文详细介绍了Spring的事务传播机制,包括REQUIRED、REQUIRES_NEW、NESTED等七种级别,并通过实例解释了它们在方法调用中的行为。同时,讨论了@Transactional注解可能导致事务失效的情况,特别是在同一类内部方法调用时,并提供了解决方案。
摘要由CSDN通过智能技术生成

Spring事务传播机制详解和 @Transactional 失效情况原因及解决方法

什么是事务传播机制

  • 事务的传播,是A方法调用B方法并将事务传递给它。事务的转播机制主要针对被调用者而言,控制它是否被传播或者被怎样传播。spring事务的传播机制有七种:

  • 传播行为描述
    PROPAGATION_REQUIRED默认的Spring事物传播级别,若当前存在事务,则加入该事务,若不存在事务,则新建一个事务
    PROPAGATION_REQUIRE_NEW若当前没有事务,则新建一个事务。若当前存在事务,则新建一个事务,新老事务相互独立。外部事务抛出异常回滚不会影响内部事务的正常提交
    PROPAGATION_NESTED如果当前存在事务,则嵌套在当前事务中执行。如果当前没有事务, 则新建一个事务,类似于REQUIRE_NEW
    PROPAGATION_SUPPORTS支持当前事务,若当前不存在事务,以非事务的方式执行
    PROPAGATION_NOT_SUPPORTED以非事务的方式执行,若当前存在事务,则把当前事务挂起
    PROPAGATION_MANDATORY强制事务执行,若当前不存在事务,则抛出异常
    PROPAGATION_NEVER以非事务的方式执行,如果当前存在事务,则抛出异常
  • 传播级别一般不需要定义,默认就是PROPAGATION_REQUIRED,除非在嵌套事务的情况。上述描述表格的描述还是比较抽象,下面我们使用一个例子来说明这个传播机制。假定方法A调用方法B:

  • 方法B定义的事务类型A方法有事务时A方法无事务
    @Transactional(propagation = Propagation.REQUIRED)B和A事务合并成一个事务B新建一个事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)B新建一个事务,和A事务无关,互不影响(A回滚不会影响到B的提交)B新建一个事务
    @Transactional(propagation = Propagation.NESTED)B新建一个A的子事务,A回滚会导致B已经提交的事务一起回滚;B回滚不会影响到AB新建一个事务
    @Transactional(propagation = Propagation.SUPPORTS)B加入到A事务中B无事务
    @Transactional(propagation = Propagation.NOT_SUPPORTED)挂起A事务,B以无事务方式执行B无事务
    @Transactional(propagation = Propagation.MANDATORY)B加入到A事务中B抛异常
    @Transactional(propagation = Propagation.NEVER)B抛异常B无事务

七种事务传播机制

  • 现在在这里,我们假定方法AStudentService类中的方法,方法BCourseService类中的方法

@Transactional(propagation = Propagation.REQUIRED)

  • A中没有事务,B中有事务

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //这里没有开启事务,courseService.insertCourse会自己开启一个事务运行
        //而且两个添加操作都会成功,因为studentMapper.insert(student);是自动提交的
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
    
            int i = 1/0;//这里抛出异常,两个添加操作都不会回滚
        }
    
    }
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.REQUIRED)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    
  • A和B两个方法都有事务

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //两个方法都使用了@Transactional(propagation = Propagation.REQUIRED)
        //courseService.insertCourse()会加入到insert0方法开启的事务中,所以两个方法在同一事务中
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
    
            int i = 1/0;//这里抛出异常,两个添加操作都被回滚
        }
        
    }
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.REQUIRED)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    

@Transactional(propagation = Propagation.REQUIRES_NEW)

在A方法的事务中抛出异常,B方法正确执行,正常提交

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //courseService.insertCourse()方法用了@Transactional(propagation = Propagation.REQUIRES_NEW)
        //开启了一个独立的新的事务,在独立的事务中运行,
        // 并且insert0()开启的事务被挂起
        //等courseService.insertCourse()运行完毕,再恢复insert0()的事务
        //两个事务的提交和回滚都在各自事务中完成
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
    
            //这里抛出异常,courseService.insertCourse()不会回滚
            //但是studentMapper.insert会被回滚
            int i = 1/0;
        }
    
    }
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    
  • 在B方法中抛出异常,A和B都被回滚

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //courseService.insertCourse()方法用了@Transactional(propagation = Propagation.REQUIRES_NEW)
        //courseService.insertCourse()会抛出异常给insert0()方法,导致两个方法都被回滚
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
            //这里调用的insertCourse会抛出异常
            courseService.insertCourse();
    
    
        }
    
    }
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
            //这里抛出异常,异常会被抛给调用这个方法的调用者
            int i = 1/0;
        }
    }
    

@Transactional(propagation = Propagation.SUPPORTS)

A方法有事务,B加入到事务中

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.SUPPORTS)
        //所以会加入到insert0()开启的事务中,被一起回滚
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
            //这里抛出异常,courseService.insertCourse()也会被回滚
            int i=1/0;
    
    
        }
    
    }
    
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.SUPPORTS)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    
    
  • A没有事务,B以无事务方式运行

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.SUPPORTS)
        //由于insert0没有开启事务,所以两个方法都以无事务方式运行,都会自动提交
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
            //这里抛出异常,courseService.insertCourse()不会被回滚
            //studentMapper.insert(student);也不会被回滚
            int i=1/0;
    
    
        }
    
    }
    
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.SUPPORTS)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    

@Transactional(propagation = Propagation.NOT_SUPPORTED)

  • A有事务,B以无事务方式运行(自动提交)

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.NOT_SUPPORTED)
        //所以courseService.insertCourse会以无事务方式运行,自动提交
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
            //这里抛出异常,courseService.insertCourse()不会被回滚
            //studentMapper.insert(student);会被回滚
            int i=1/0;
    
    
        }
    
    }
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.NOT_SUPPORTED)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    

@Transactional(propagation = Propagation.MANDATORY)

  • A有事务,B加入事务中

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.MANDATORY)
        //所以courseService.insertCourse会加入到insert0()的事务中,一起回滚
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
            //这里抛出异常,courseService.insertCourse()会被回滚
            //studentMapper.insert(student);会被回滚
            int i=1/0;
    
        }
        
       
    }
    
    
    @Service
    public class CourseService {
    
    
        @Autowired
        private CourseMapper courseMapper;
    
        @Transactional(propagation = Propagation.MANDATORY)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    
  • A没有事务,B会抛出异常

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.MANDATORY)
        //courseService.insertCourse();会抛出异常
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
        }
    
    }
    
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.MANDATORY)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    

@Transactional(propagation = Propagation.NEVER)

  • A方法无事务,A和B都以无事务方式运行

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.NEVER)
        //courseService.insertCourse();以无事务方式运行,两个添加都不会被回滚
        public void insert0(){
    
            courseService.insertCourse();
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
            //这里抛出异常,但是两个添加操作都是自动提交的,都不会被回滚
            int i = 1/0;
    
        }
    
    }
    
    @Service
    public class CourseService {
    
    
        @Autowired
        private CourseMapper courseMapper;
    
        @Transactional(propagation = Propagation.NEVER)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    
  • A方法有事务,B抛出异常

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.NEVER)
        //由于insert0()开启了一个事务,所以courseService.insertCourse();会抛出异常
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
    
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
            //这里会抛出异常,因为courseService.insertCourse不支持事务
            courseService.insertCourse();
    
        }
    
    }
    
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.NEVER)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    

@Transactional(propagation = Propagation.NESTED)

  • A方法抛出异常,B方法成功的提交也被回滚

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.NESTED)
        //由于insert0()开启了一个事务,所以courseService.insertCourse();在嵌套事务内层运行
        //当courseService.insertCourse()成功提交后,insert0()最后抛出异常,会导致courseService.insertCourse()也会被回滚
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            try {
                courseService.insertCourse();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
            //这里抛出异常会导致courseService.insertCourse()成功的提交也被回滚
            //studentMapper.insert(student)提交的也会被回滚
            int i = 1/0;
        }
    
    }
    
    
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.NESTED)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
    
        }
    }
    
  • A方法执行成功,B方法抛出异常,只有B的提交被回滚,A的提交成功执行

  • 
    @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.NESTED)
        //由于insert0()开启了一个事务,所以courseService.insertCourse();在嵌套事务内层运行
        //当courseService.insertCourse()抛出异常会被catch,insert0会成功执行
        //最后,insert0成功提交,courseService.insertCourse()被回滚了
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            try {
                courseService.insertCourse();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
    
        }
    
    }
    
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.NESTED)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
            //这个方法抛出异常,只会回滚当前这个方法
            int i = 1/0;
        }
    }
    
  • A方法提交成功,B方法也提交成功

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
        //由于courseService.insertCourse使用@Transactional(propagation = Propagation.NESTED)
        //由于insert0()开启了一个事务,所以courseService.insertCourse();在嵌套事务内层运行
        //当courseService.insertCourse()抛出异常会被catch,insert0会成功执行
        //最后,insert0成功提交,courseService.insertCourse()被回滚了
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            try {
                courseService.insertCourse();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
    
        }
    
    }
    
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.NESTED)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
        }
    }
    
  • B方法都用@Transactional(propagation = Propagation.REQUIRES_NEW)来修饰,是否也能达到这个效果呢?

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private CourseService courseService;
    
    
    
    
        @Transactional(propagation = Propagation.REQUIRED)
        public void insert0(){
    
            try {
                //由于这个方法使用了@Transactional(propagation = Propagation.REQUIRES_NEW)
                //尽管内部抛出异常,但是,insert0()方法的事务不会被影响
                courseService.insertCourse();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
    
        }
    
    }
    
    
    
    @Service
    public class CourseService {
    
        @Autowired
        private CourseMapper courseMapper;
    
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void insertCourse(){
            Course course = new Course();
            course.setId(1);
            course.setName("course_"+  System.currentTimeMillis());
            courseMapper.insert(course);
    
            int i = 1/0;
        }
    }
    

无事务运行

  • @Service
    public class StudentService {
    
    
        @Autowired
        private StudentMapper studentMapper;
    
    
    
        //没有使用@Transactional注解,以无事务方式运行
        //studentMapper.insert(student);自动提交,不会被回滚
        public void insert0(){
    
            Student student = new Student();
            student.setId(1);
            student.setName("student_"+ System.currentTimeMillis());
            studentMapper.insert(student);
    
            int i = 1/0;//这里抛出异常,但是studentMapper.insert会自动提交,不会被回滚
    
    
        }
    
    }
    

事务失效情况

使用了@Transactional的方法,被同一个类里面的无@Transactional方法调用,@Transactional的方法无效。

  • 下面的这种情况,student表 和 source表 都能成功添加数据,回滚失败。注意:这是在同一个类中的方法相互调用,上述的是不同类的方法调用,上下文不违背!

  • @Service
    public class StudentImpl implements IStudent {
    
        @Autowired
        public StudentMapper studentMapper;
    
        @Autowired
        public SourceMapper sourceMapper;
    
        @Autowired
        public ISource source;
    
    	@Override
        public void insert0() {
            Student student = new Student();
            student.setId(1);
            student.setName("student:123-sad");
            studentMapper.insert(student);
            
            insertProxy();
        }
    
        @Transactional
        public void insertProxy(){
            Source source = new Source();
            source.setId(210);
            source.setName("source:210=qqwe");
            sourceMapper.insert(source);
            
            int i = 1/0;
        }
    
  • 但是下面这种情况B方法是可以回滚成功的,但A方法不能回滚,与第二章说明的情况一致

  • @Service
    public class StudentImpl implements IStudent {
    
        @Autowired
        public StudentMapper studentMapper;
    
        @Autowired
        public SourceMapper sourceMapper;
    
        @Autowired
        public ISource source;
    
    	@Override
        public void insert0() {
            Student student = new Student();
            student.setId(1);
            student.setName("student:123-sad");
            studentMapper.insert(student);
            
            insertProxy();
        }
    
    	//无论这里有没有@Transactional注解,source.insert0()一样能回滚成功
        @Transactional	
        public void insertProxy(){
    		source.insert0();
        }
        
    
        
    @Service
    public class SourceImpl implements ISource {
    
        @Autowired
        public SourceMapper sourceMapper;
    
        @Override
        @Transactional
        public void insert0() {
            Source source = new Source();
            source.setId(210);
            source.setName("source:210=qqwe");
            sourceMapper.insert(source);
    
            int i = 1/0;
    
        }
    }
    
  • 原因:Spring的事务管理是基于动态代理对象的代理逻辑实现的,那么如果在类内部的非事务方法调用类内部的事务方法,这个调用事务方法的过程并不是通过代理对象来调用的,而是直接通过this对象来调用方法,绕过的代理对象,肯定就是没有代理逻辑了。

  • 解决方法:使用在类中注入自己的bean,加上@Lazy是为了防止bean的循环依赖注入。但是在实际开发中很少这样写,但这样确实能解决@Transactional失效的问题

  • @Service
    public class StudentImpl implements IStudent {
    
        @Autowired
        public StudentMapper studentMapper;
    
        @Autowired
        public SourceMapper sourceMapper;
    
        @Autowired
        public ISource source;
    
        @Autowired
        @Lazy
        public StudentImpl studentImpl;
    
        @Override
        public void insert0() {
    
            Student student = new Student();
            student.setId(1);
            student.setName("student:123-sad");
            studentMapper.insert(student);
    
            studentImpl.insertProxy();
        }
    
    	//insertProxy()方法能成功回滚,Source表没有数据,但insert0()还是会添加成功,Student表有数据
        @Transactional
        public void insertProxy(){
            Source source1 = new Source();
            source1.setId(999);
            source1.setName("source:999=qqwe");
            sourceMapper.insert(source1);
    
            int i = 1/0;
        }
    }
    

奇特的回滚方式

  • 我们都知道,在Service层打上@Transactional后,若在该层操作出错了,不捕获异常,交由Controller层去捕获,则会回滚;但是如果异常在Service层就被捕获了,则不会回滚。但有以下方式,即使在Service层捕获了异常,仍然可以回滚成功。

  • @RestController
    public class InsertController {
    
        @Autowired
        public IStudent studentService;
    
        @GetMapping("/insert")
        public String insert(){
            String result = "error";
            try {
                result = studentService.insert0();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    }
    
    @Service
    public class StudentImpl implements IStudent {
        @Autowired
        public ISource sourceService;
    
        @Override
        @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
        public String insert0() throws Exception {
            String result = sourceService.insert0();
            if ("fail".equals(result)) {
                throw new Exception();
            }
            return "OK";
        }
    }
    
    
    @Service
    public class SourceImpl implements ISource {
    
        @Autowired
        public SourceMapper sourceMapper;
    
        @Override
        @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
        public String insert0() throws Exception{
            String result = "success";
            try {
                Source source = new Source();
                source.setName("source:210=qqwe");
                sourceMapper.insert(source);
    
                int i = 1/0;
            }catch (Exception e){
                result = "fail";
            }
            return result;
        }
    }
    
  • 这是因为A方法调用了B方法,A方法和B方法组成了一个事务,虽然B方法异常确实是被捕获到了,但是抛出异常的是A方法,由于A方法和B方法已经组成了一个事务了,所以这两个方法会一起回滚!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT枫斗者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值