Spring事务传播行为问题解决

这篇文章主要介绍了Spring事务传播行为问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一、简介

Spring事务配置及相关说明详见:https://www.jb51.net/article/177710.htm。这里说明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进行调用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Spring中使用atomikos+druid实现经典分布式事务的方法

    经典分布式事务,是相对互联网中的柔性分布式事务而言,其特性为ACID原则,包括原子性(Atomictiy).一致性(Consistency).隔离性(Isolation).持久性(Durabilit): 原子性:事务是一个包含一系列操作的原子操作.事务的原子性确保这些操作全部完成或者全部失败. 一致性:一旦事务的所有操作结束,事务就被提交.然后你的数据和资源将处于遵循业务规则的一直状态. 隔离性:因为同时在相同数据集上可能有许多事务处理,每个事务应该与其他事务隔离,避免数据破坏. 持久性:一旦事

  • SpringBoot内部调用事务不起作用问题的解决方案

    在做业务开发时,遇到了一个事务不起作用的问题.大概流程是这样的,方法内部的定时任务调用了一个带事务的方法,失败后事务没有回滚.查阅资料后,问题得到解决,记录下来分享给大家. 场景 我在这里模拟一个场景,大概的调用方式就如下面的代码这样. @Override @Transactional(rollbackFor = RuntimeException.class) public void insertUser(User user) { userMapper.insertUser(user); thr

  • Springboot-dubbo-fescar 阿里分布式事务的实现方法

    大家可以自行百度下阿里分布式事务,在这里我就不啰嗦了.下面是阿里分布式事务开源框架的一些资料,本文是springboot+dubbo+fescar的集成. 快速开始 https://github.com/alibaba/fescar/wiki/Quick-Start GIT地址 https://github.com/alibaba/fescar 1.sql CREATE TABLE `undo_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `br

  • springboot中事务管理@Transactional的注意事项与使用场景

    前言:在service层的方法上使用@Transactional 即可实现处理数据库发生错误时触发事务回滚机制. 注意: Spring 基于注解的声明式事物 @Transactional 默认情况下只会对运行期异常(java.lang.RuntimeException及其子类)和 Error 进行回滚. 数据库引擎要支持事物,使用InnoDB. @Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没

  • SpringBoot+Dubbo+Seata分布式事务实战详解

    前言 Seata 是 阿里巴巴开源的分布式事务中间件,以高效并且对业务0侵入的方式,解决微服务场景下面临的分布式事务问题. 事实上,官方在GitHub已经给出了多种环境下的Seata应用示例项目,地址:https://github.com/seata/seata-samples. 为什么笔者要重新写一遍呢,主要原因有两点: 官网代码示例中,依赖太多,分不清哪些有什么作用 Seata相关资料较少,笔者在搭建的过程中,遇到了一些坑,记录一下 一.环境准备 本文涉及软件环境如下: SpringBoot

  • SpringDataMongoDB多文档事务的实现

    一.安装MongoDB4.0.3(××) 1.1.官方安装文档 https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/ 1.2.tar.gz包下载地址 https://www.mongodb.com/download-center/community?jmp=docs 1.3.复制集官方配置 https://docs.mongodb.com/manual/administration/replica-set-mem

  • Spring中的事务传播行为示例详解

    一.背景介绍 Spring 框架应该是每一个人 javaer 都必须接触和学习的技术,Spring 公司所提供的各种框架是 Java 开发行业可参考的重要标准之一. Spring 中有 7 种类型的事务传播行为.事务传播行为是 Spring 框架提供的一种事务管理方式,它是 Spring 框架之中非常重要的一个技术点,毕竟事务关系到应用程序和数据库的交互,而数据更是互联网行业最为重要的资源. 平时开发过程中事务都会有使用,但是没有真正地总结过,尤其是事务中嵌套事务的场景,此篇基础知识文在此做一个

  • Spring编程式和声明式事务实例讲解小结

    Spring事务管理 Spring支持两种方式的事务管理: 编程式事务管理: 通过Transaction Template手动管理事务,实际应用中很少使用, 使用XML配置声明式事务: 推荐使用(代码侵入性最小),实际是通过AOP实现 实现声明式事务的四种方式: 基于 TransactionInterceptor 的声明式事务: Spring 声明式事务的基础,通常也不建议使用这种方式,但是与前面一样,了解这种方式对理解 Spring 声明式事务有很大作用. 基于 TransactionProx

  • Spring事务传播行为问题解决

    这篇文章主要介绍了Spring事务传播行为问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.简介 Spring事务配置及相关说明详见:https://www.jb51.net/article/177710.htm.这里说明spring事务的几点注意: 1.默认只会检查回滚RuntimeException的异常. 2.@Transactional注解只能作用于public的方法上,默认传播行为 Propagation.REQUIRED

  • 关于spring事务传播行为非事务方式的理解

    目录 spring事务传播行为非事务方式 Spring事务理解和配置 1 Spring事务 1.1 事务简介 1.2 事务的传播行为 1.3 编程式事务(需要手动写代码,了解) 1.4 声明式事务(xml配置) 1.5 声明式事务(注解) spring事务传播行为非事务方式 具体的隔离级别可以看看搜一下,相关的博客挺多的,现在说一下对传播行为 PROPAGATION_NOT_SUPPORTED.PROPAGATION_NEVER中很多解释为 非事务方式运行 的理解.    关于什么是'非事务方式

  • Spring事务传播属性和隔离级别详细介绍

    1 事务的传播属性(Propagation) 1) REQUIRED ,这个是默认的属性 Support a current transaction, create a new one if none exists. 如果存在一个事务,则支持当前事务.如果没有事务则开启一个新的事务. 被设置成这个级别时,会为每一个被调用的方法创建一个逻辑事务域.如果前面的方法已经创建了事务,那么后面的方法支持当前的事务,如果当前没有事务会重新建立事务. 2) MANDATORY Support a curren

  • Spring事务传播中嵌套调用实现方法详细介绍

    目录 前言 7种传播方式 注解式事务 事务的方法之间的调用 注意事项 前言 最近在使用Spring框架时遇到了一些问题,主要是Spring的事务传播问题,一个不带事务的方法调用带事务的方法,有时候会出现不回滚的情况,所以写了这篇文章来记录一下. 7种传播方式 我们先来看Spring事务的7中传播方式以及对应的描述 属性名称 值 描述 PROPAGATION__REQUIRED REQUIRED 表示的是当前这个方法必须运行在一个事务环境中,如果当前方法已经处于事务环境中,就可以直接使用该方法,否

  • 浅谈Spring事务传播行为实战

    Spring框架提供了事务管理的标准实现,且可以通过注解或者XML文件的方式声明和配置事务. 通过异步事件的方式解耦服务调用,可以提高程序的响应速度,并且避免因为事务传播行为而导致的事务问题. 本文以一个电商平台包裹出库的业务为实际背景,通过异步事件与线程池的方式解耦嵌套事务,提高程序并发性能:为了便于问题的分析和方案的理解,同时还讲解了Spring的事务管理,并着重介绍了几种不同的事务传播行为. 事务小贴士 什么是事务呢?简单来讲事务就是逻辑上的一组操作,这些操作要么都执行,要么都不执行. 什

  • 深入理解Spring的事务传播行为

    前言 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为.事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为.这是Spring为我们提供的强大的工具箱,使用事务传播行可以为我们的开发工作提供许多便利.但是人们对他的误解也颇多,你一定也听过"service方法事务最好不要嵌套"的传言.要想正确的使用工具首先需要了解工具.本文对七种事务传播行为做详细介绍,内容主要代码示例的方式呈现. 基础概念 1. 什么是事务传播行

  • Spring源码解析之事务传播特性

    一.使用方式 可以采用Transactional,配置propagation即可. 打开org.springframework.transaction.annotation.Transactional可见默认传播特性是REQUIRED. /** * The transaction propagation type. * <p>Defaults to {@link Propagation#REQUIRED}. * @see org.springframework.transaction.inte

  • 老生常谈spring的事务传播机制

    目录 spring的事务传播机制 1.why 为什么会有事务传播机制? 2.传播机制生效的条件 解决方案 3.传播机制类型 PROPAGATION_REQUIRED (默认) REQUIRES_NEW (一般用在子方法需要单独事务) NESTED SUPPORTS NOT_SUPPORTED MANDATORY NEVER spring的事务传播机制 背景:实习期间几次遇到事务方法,有一次本地测试时发现事务没有回滚,就把简单描述写在wx上,今天来给spring事务做个自我总结. 1.why 为什

  • Spring事务的七种传播行为

    目录 一.什么是事务传播行为 二.事务的传播行为有哪些? 一.什么是事务传播行为 什么叫事务传播行为?听起来挺高端的,其实很简单.即然是传播,那么至少有两个东西,才可以发生传播.单体不存在传播这个行为.所为的事务传播行为就是多个声明的事务的方法 相互调用的时候,这个事务该如何传递 如上图:methodA()调用methodB()那么这两个方法都显示了开启事务,那么methodB()开启一个新的事务,还是继续在methodA()这个事务里面去执行,就去决所谓的事务传播的一个行为 二.事务的传播行为

  • 深入了解Spring的事务传播机制

    目录 Spring 事务传播机制有哪些? 事务传播机制使用与演示 REQUIRED 使用演示 REQUIRED_NEW 使用演示 NESTED 使用演示 总结 Spring 事务传播机制是指,包含多个事务的方法在相互调用时,事务是如何在这些方法间传播的. 既然是“事务传播”,所以事务的数量应该在两个或两个以上,Spring 事务传播机制的诞生是为了规定多个事务在传播过程中的行为的.比如方法 A 开启了事务,而在执行过程中又调用了开启事务的 B 方法,那么 B 方法的事务是应该加入到 A 事务当中

随机推荐