前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >fix bug:Spring中事务不生效的问题

fix bug:Spring中事务不生效的问题

作者头像
关忆北.
发布2021-12-07 16:49:20
7120
发布2021-12-07 16:49:20
举报
文章被收录于专栏:关忆北.关忆北.关忆北.

事务注解不生效的问题

出现该问题的主要原因主要有两点:

  • Spring的事务没有生效
  • 出现异常时无法正常回滚

Spring事务不生效的情况

  1. @Transactional用在非public方法上
  2. 未通过代理手段调用事务方法

事务注解用在非public方法上 @Transactional private Access createRecords(AccessDto accessDto); 未通过代理调用的情况:Service正常注入Spring中,在调用方法时使用This调用事务方法,Spring不会注入this,所以无法使用事务。自己调用自己时可以使用Controller直接调用Service //AccessServiceImpl.class //this.AccessRecords(AccessDto accessDto);

出现异常时无法回滚的情况

  1. 未正确处理异常,事务生效也不一定能回滚
  2. 多次数据库操作,未配置事务传播

事务生效不能回滚的情况: try/catch包裹标记了@Transactional注解的方法,方法满足一定条件时才会回滚。 一定条件: ①:只有异常传播除了标记的@Transactional注解的方法,事务才会回滚。 ②:默认情况下,出现RunTimeException(非受检异常)或Error的时候,Spring才会回滚事务。 ③:catch的作用就是捕捉方法中的异常,使回滚不传播到外层事务,以免对其他事务产生影响。


 public int createUserWrong1(String name) {
 try {
     this.createUserPrivate(new UserEntity(name));
 } catch (Exception ex) {
     log.error("create user failed because {}", ex.getMessage());
 }
 return userRepository.findByName(name).size();
}

RunTimeException是Exception的子类,Exception包裹了所有的异常,导致异常无法传播出去,导致无法回滚。 ①的解决方案 方案一、手动设置回滚:


 //catch异常时:
 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

方案二、使用@Transactional注解的属性


 //抛出任何异常时均回滚 
@Transactional(rollbackFor = Exception.class)

上文的方案在这种情况下显然是不适用的:

用户注册时在主表中新增数据,同时需要在子表中关联主表数据,现在业务要求,子表执行错误时回滚,子表不影响主表事务,也就是子表不能影响主流程,需要主表和子表不在同一个事务中。

解决方案:

@Transactional(propagation = Propagation.REQUIRES_NEW)

执行到当前方法时创建一个新的事务。

官方文档:

/**
 * Create a new transaction, and suspend the current transaction if one exists.
 * Analogous to the EJB transaction attribute of the same name.
 * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
 * on all transaction managers. This in particular applies to
 * {@link org.springframework.transaction.jta.JtaTransactionManager},
 * which requires the {@code javax.transaction.TransactionManager} to be
 * made available to it (which is server-specific in standard Java EE).
 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManage
 */
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-07-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 事务注解不生效的问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档