如何解决Spring事务中传播行为的问题

这篇文章将为大家详细讲解有关如何解决Spring事务中传播行为的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

浮梁网站制作公司哪家好,找成都创新互联!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设公司等网站项目制作,到程序开发,运营维护。成都创新互联从2013年成立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联

一、简介

这里说明spring事务的几点注意:

1、默认只会检查回滚RuntimeException的异常。

2、@Transactional注解只能作用于public的方法上,默认传播行为 Propagation.REQUIRED

3、service内部方法之间的调用,不会被spring拦截到,也即不会产生事务

二、坑点

主要的坑点就是在嵌套事务上,当service内部方法之间调用的时候,很可能会产生预期之外的效果。例如下例子:

saveUser保存用户,如果过程出现异常,则执行saveMsg方法。

public class UserServiceImpl implements UserService{
 
  @Autowired
  private UserDao userDao;
  @Autowired
  private MsgDao msgDao;
  @Autowired
  private MsgService msgService;
    @Autowired
    private UserService userService;
 
   
  @Transactional(propagation = Propagation.REQUIRED)
  public void saveUser(User user) throws Exception {
    System.out.println(user.toString());
    try {
      userDao.saveUser(user);
      int i = 1/0;
//     saveUser2(user);
    } catch (Exception e) {
//     msgService.saveMsg();
//           this.saveMsg();
      userService.saveMsg();
      throw new RuntimeException();
    }
  }
   
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void saveMsg() {
    TbMsg msg = TbMsg.builder().name("xiaocao").msg("xiaoxiao").age(27).build();
    msgDao.saveMsg(msg);
  }
}

单元测试,调用saveUser方法,并没有达到想要的效果(saveUser异常,SaveMsg隔离级别是REQUIRES_NEW,理论上应该能入库)。

失败原因即是上面第一节中说的:同一个service中的方法调用,不会产生新事务。Spring 事务的管理控制,主要是通过AOP的动态代理增强来实现的,目标对象本身并没有任何的事务管理能力,都是通过代理对象动态增强功能去实现事务管理。在同一个service中的方法调用,相当于是目标对象本身的this调用,并没有经过代理对象,所以自然的事务配置的嵌套均无效。

解决策略:

1、saveMsg移动到另一个service中,在UserServiceImpl中导入MsgService,saveUser中通过MsgService类去调用。

2、UserServiceImpl中注入自己,通过注入的自身service进行调用。

关于“如何解决Spring事务中传播行为的问题”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。


本文名称:如何解决Spring事务中传播行为的问题
标题来源:http://azwzsj.com/article/ijcsdg.html