当前位置: 首页 > news >正文

Spring——事务的传播性

   

目录

REQUIRED

REQUIRES_NEW

NESTED

MANDATORY

事务的回滚规则


    事务的传播性(Transaction Propagation)是Spring事务管理的一个重要概念,它定义了在多个事务方法相互调用时,事务应该如何传播。Spring框架提供了7种传播行为,这些行为在TransactionDefinition接口中定义。

  1. PROPAGATION_REQUIRED(默认):

    • 如果当前存在事务,则加入该事务。

    • 如果当前没有事务,则创建一个新的事务。

  2. PROPAGATION_SUPPORTS

    • 如果当前存在事务,则加入该事务。

    • 如果当前没有事务,则以非事务的方式继续运行。

  3. PROPAGATION_MANDATORY

    • 如果当前存在事务,则加入该事务。

    • 如果当前没有事务,则抛出异常。

  4. PROPAGATION_REQUIRES_NEW

    • 创建一个新的事务,如果当前存在事务,则把当前事务挂起。

    • 新事务与原有事务相互独立,互不干扰。

  5. PROPAGATION_NOT_SUPPORTED

    • 以非事务方式运行,如果当前存在事务,则把当前事务挂起。

    • 这意味着该方法不会在事务中运行。

  6. PROPAGATION_NEVER

    • 以非事务方式运行,如果当前存在事务,则抛出异常。

  7. PROPAGATION_NESTED

    • 如果当前存在事务,则创建一个嵌套事务(嵌套事务是当前事务的一个子事务)。

    • 如果当前没有事务,则行为与PROPAGATION_REQUIRED一样。

    • 嵌套事务可以独立于外部事务进行提交或回滚。如果外部事务回滚,则嵌套事务也会回滚;而嵌套事务回滚不会影响外部事务,除非外部事务捕获了嵌套事务的异常并标记为回滚。


先准备两个service,在其中一个service的方法内去调用另外一个service的方法:设置传播性的方法是在@Transactional注解给propagation赋值

AService

public class UserService {@Autowiredprivate UserDao userDao;@Transactionalpublic void up(){User user = new User();user.setUid(1);user.setUsername("cc");userDao.update( user);}
}

BService

@Service
public class UserService2 {@Autowiredprivate UserDao userDao;@Autowiredprivate UserService userService;@Transactionalpublic void up(){User user = new User();user.setUid(2);user.setUsername("aa");userDao.update(user);userService.up();}
}

REQUIRED

    REQUIRED是spring事务默认的传播行为,如果当前存在事务,则加入该事务,如果没有事务,就会创建一个新的事务。

    如该示例所示,在B中的up方法先进行一次修改操作,然后在A中的up方法内抛出异常。

    启动之后,两条数据都没有修改,说明两个事务合并成一个回滚

    接下来换种方式,在B中调用A方法后抛出,看是否回滚。

    结局依旧是回滚。

REQUIRES_NEW

    该行为如果当前存在事务,则会把当前事务挂起。

    将A事务传播性修改为REQUIRES_NEW,然后在不抛出异常的情况下先运行一遍:

    结果发现程序似乎卡死了。。。

    先捋一遍过程:B先开启事务B执行update语句,之后再调用A中的up方法,由于该传播行为下是两个独立的事务,所以开启事务A。

    但是!这两个update的语句涉及的字段并没有索引导致InnoDB使用的是表锁,事务B并没有提交,所以事务A卡在了update语句上。相关内容:MySQL——锁-CSDN博客

    给username加上索引之后,InnoDB使用行锁,而这里操作的数据并不是同一行,所以数据成功被修改。


    接下来测试该传播行为如何回滚:

在外面一层抛出异常

    结果为,外面层成功回滚,而里面的事务提交。后面反过来测试一下:

    发现两个事务都回滚了。当然如果里面的异常被处理了则不会回滚。

NESTED

    如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则等价于REQUIRED。

    该事务行为就相当于外部事务的子事务,如果外部事务回滚,则子事务也会跟着回滚。里面的事务回滚的话,不会影响外部事务(前提是要处理异常)。

    @Transactionalpublic void up(){User user = new User();user.setUsername("aa");user.setPassword("aaa");userDao.updateP(user);try{userService.up();}catch (Exception e){}}

MANDATORY

    MANDATORY事务行为,如果当前存在事务就加入该事务,如果没有就抛出异常。

    将内部事务行为改为MANDATORY,然后将外部的注解删除,尽管代码没有问题依旧会报错。


事务的回滚规则

Spring 声明式事务默认只对 “未受检异常” 回滚,具体包括:

  1. RuntimeException及其子类(如NullPointerExceptionIndexOutOfBoundsException);
  2. Error及其子类(如OutOfMemoryError)。

而对于 “受检异常”(需要显式try-catchthrows声明的异常,如IOExceptionSQLException),默认不会回滚,事务会正常提交。

http://www.dtcms.com/a/446191.html

相关文章:

  • 【优化】Mysql指定索引查询或忽略某个索引
  • 网站伪静态steam交易链接可以随便给别人吗
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(5):语法 +考え方18+2022年7月N1
  • Postman-win64-8.6.2-Setup安装教程(附详细步骤,Win64版Postman下载安装指南)
  • 关于软错误的常见问题解答
  • LLM 只会生成文本?用 ReAct 模式手搓一个简易 Claude Code Agent
  • 如果给公司做网站深圳网站建设费用大概
  • 【开题答辩全过程】以 Python在浙江省人口流动数据分析与城市规划建议的应用为例,包含答辩的问题和答案
  • InputReader与InputDispatcher关系 - android-15.0.0_r23
  • 基于Android Framework的C/C++开发实战
  • 个人主页网站制作教程营销策划的六个步骤
  • 第7章树和二叉树:二叉树的定义和性质
  • 网站建设首选玖艺建站信得过wordpress企业主题下载
  • TDengine 比较函数 IFNULL 用户手册
  • 【2026计算机毕业设计】基于jsp的毕业论文管理系统
  • 最小二乘问题详解3:线性最小二乘实例
  • OneData:数据驱动与AI落地的统一数据底座方法论——从规范到实践的全链路拆解
  • 与众不同的网站wordpress内容批量替换
  • 自己做网站要买什么微信制作网站设计
  • 笔记·线性回归(属于监督学习)
  • 同国外做贸易的网站怎么查看网站是用什么系统做的
  • 打印机专题
  • Vue 虚拟列表实现方案详解:三种方法的完整对比与实践
  • Oracle OCP认证考试题目详解082系列第48题
  • 第一章:单例模式 - 武林中的孤高剑客
  • sql题目基础50题
  • 哪些网站做的最好网站建设功能报
  • 第十三章:眼观六路,耳听八方——Observer的观察艺术
  • Kubernetes集群安全机制
  • 建站行业的发展趋势网站建设网络