Spring 50例常见错误(十七)

文章整理来源:Spring编程常见错误50例_spring_spring编程_bean_AOP_SpringCloud_SpringWeb_测试_事务_Data-极客时间

案例42:事务的传播机制

        希望的结果是,当注册课程发生错误时,只回滚注册课程部分,保证学生信息依然正常,即希望在内层事务抛出了异常,但外层的数据能够保留。 而实际是内外层的数据都回滚了

// 外层事务-保存学生信息,并关联课程
@Service
public class StudentService {
  //省略非关键代码
  @Transactional(rollbackFor = Exception.class)
  public void saveStudent(String realname) throws Exception {
      Student student = new Student();
      student.setRealname(realname);
      studentService.doSaveStudent(student);
      try {
          courseService.regCourse(student.getId());
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  //省略非关键代码
}
------------------------------------------------
// 内层事务-并关联课程
@Service
public class CourseService {
    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private StudentCourseMapper studentCourseMapper;

    // 注意这个方法标记了“Transactional”,并抛出了异常
    @Transactional(rollbackFor = Exception.class)
    public void regCourse(int studentId) throws Exception {
        studentCourseMapper.saveStudentCourse(studentId, 1);
        courseMapper.addCourseNumber(1);
        throw new Exception("注册失败");
    }
}

        解析:在 Spring 声明式的事务处理中,有一个属性 propagation,

        其中 propagation 有 7 种配置:REQUIREDSUPPORTSMANDATORYREQUIRES_NEWNOT_SUPPORTEDNEVERNESTED。默认是 REQUIRED,它的含义是:如果本来有事务,则加入该事务,如果没有事务,则创建新的事务。

        Spring 事务处理的核心,其关键实现参考 TransactionAspectSupport.invokeWithinTransaction(),该方法流程: 1. 检查是否需要创建事务;2. 调用具体的业务方法进行处理;3. 提交事务; 4. 处理异常。

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
      final InvocationCallback invocation) throws Throwable {
 
   TransactionAttributeSource tas = getTransactionAttributeSource();
   final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
   final PlatformTransactionManager tm = determineTransactionManager(txAttr);
   final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
   if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
      // 是否需要创建一个事务
      TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
      Object retVal = null;
      try {
         // 调用具体的业务方法
         retVal = invocation.proceedWithInvocation();
      }
      catch (Throwable ex) {
         // 当发生异常时进行处理
         completeTransactionAfterThrowing(txInfo, ex);
         thr
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值