【Spring】本地事务

一、事务的基本性质

  • 原子性:一系列操作整体不可拆分,要么同时成功,要么同时失败。(下订单、减库存、减积分)
  • 一致性:数据在事务的前后,业务整体一致。(存取钱的总数量)
  • 隔离性:事务之间互相隔离。
  • 持久性:一旦事务成功,数据一定会落盘在数据库。

二、事务的隔离级别

事务的隔离级别(Transaction Isolation Levels)定义了在并发执行的事务中,一个事务对其他事务的操作的可见性和影响。SQL标准定义了四种常见的隔离级别,按隔离程度从低到高排序,分别是:

  1. 读未提交(Read Uncommitted)

    • 在此隔离级别下,一个事务可以读取另一个事务尚未提交的修改。这种级别可能导致脏读(Dirty Read),即读取到一个事务未提交的、不一致的数据。
    • 脏读:一个事务读取到另一个事务正在修改但未提交的数据,若第二个事务回滚,则第一个事务读取到的数据不准确。
  2. 读已提交(Read Committed)

    • Oracle和SQL Server的默认隔离级别。
    • 该隔离级别保证一个事务只能读取到已经提交的数据。也就是说,一个事务只能看到其他事务已经提交的结果。
    • 但它仍然存在不可重复读(Non-repeatable Read)的情况。即,在同一事务中,多次读取同一数据时,数据可能会在事务过程中被其他事务修改。
  3. 可重复读(Repeatable Read)

    • 在此隔离级别下,事务中读取的数据在整个事务期间都是一致的,即同一查询多次执行时结果不会变化,避免了不可重复读的问题。
    • 但此级别仍可能出现幻读(Phantom Read)。幻读指的是在同一个事务中,第一次查询某个范围的数据后,第二次查询同一范围时,可能会看到其他事务插入的新的数据行。
    • MYSQL的默认隔离级别。MySQL数据库的InnoDB引擎可以通过next-key locks机制来避免幻读。
  4. 串行化(Serializable)

    • 在该隔离级别下事务都是串行顺序执行的,MySQL数据库的 InnoDB 引擎会给读操作隐式加一把读共享锁,从而避免了脏读、不可重读复读和幻读问题。

示例:

 @Transactional(isolation = Isolation.READ_COMMITTED)- Isolation.READ_UNCOMMITTED:允许脏读。- Isolation.READ_COMMITTED:禁止脏读,允许不可重复读。- Isolation.REPEATABLE_READ:禁止脏读和不可重复读,允许幻读。- Isolation.SERIALIZABLE:禁止所有并发问题(脏读、不可重复读、幻读)。

三、事务的传播行为

传播行为说明适用场景
PROPAGATION.REQUIRED如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务。该设置是最常用的设置。最常用,适用于大多数业务方法。
PROPAGATION.SUPPORTS支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。某些方法可以在事务中执行,也可以在非事务模式下执行,通常用于查询操作。
PROPAGATION.MANDATORY支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。确保方法必须在事务中执行,若外部没有事务,则会抛出异常。
PROPAGATION.REQUIRES_NEW创建新事务,无论当前存不存在事务,都创建新事务。需要独立事务执行的操作,如日志记录或外部系统调用等。
PROPAGATION.NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。不希望当前方法在事务中执行的操作,通常用于日志、非数据库操作等场景。
PROPAGATION.NEVER以非事务方式执行,如果当前存在事务,则抛出异常。必须确保方法不在事务中执行。
PROPAGATION.NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION.REQUIRED 类似的操作。支持事务嵌套,适用于需要回滚部分操作但不影响外部事务的场景。

事务传播行为示例:

    @Transactionalpublic void methodA() {methodB();methodC(); }@Transactional(propagation = Propagation.REQUIRED)public void methodB() {}@Transactional(propagation = Propagation.REQUIRES_NEW)public void methodC() {}

事务执行顺序:

假设我们执行 methodA()

  1. 调用 methodA

    • methodA 被调用时,由于 @Transactional 默认使用 Propagation.REQUIRED,它会启动一个事务(假设当前没有事务的话)。
    • 这时,methodA 进入事务上下文。
  2. 调用 methodB

    • methodA 中调用 methodB 时,由于 methodB 的传播行为是 Propagation.REQUIRED,如果已经存在事务(即 methodA 创建的事务),methodB 会加入这个现有事务。
    • 因此,methodBmethodA 会共享同一个事务。
  3. 调用 methodC

    • methodA 中调用 methodC 时,由于 methodC 的传播行为是 Propagation.REQUIRES_NEW,它会始终开启一个新的事务。
    • methodC 的事务会挂起 methodA 中的事务,methodC 会在自己的事务中执行。methodC 执行完后,methodA 的事务会恢复。
    • methodCmethodA / methodB 的事务是独立的,methodC 完成后,methodA 会继续执行。

四、本类方法调用事务失效

同一个对象内事务方法互相调用默认失败,因为绕过了代理对象。相当于b、c的事务不会生效,和a共用一个事务。

示例:

   @Transactional(timeout = 30)public void a(){b();c();}@Transactional(propagation = Propagation.REQUIRED,timeout = 2)public void b(){}@Transactional(propagation = Propagation.REQUIRES_NEW,timeout = 20)public void c(){}

解决:

  1. 引入aop依赖,使用里面的aspectj做动态代理
        <!--引入aop依赖,使用里面的aspectj做动态代理--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
  1. 开启aspectj动态代理功能,并对外暴露代理对象。以后所有动态代理都是用aspectj创建(即便没有接口也可以创建动态代理)
@EnableAspectJAutoProxy(exposeProxy= true)
  1. 使用动态代理调用
    @Transactional(timeout = 30)public void a(){OrderServiceImpl orderService = (OrderServiceImpl) AopContext.currentProxy();orderService.b();orderService.c();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/60190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始的 Hugging Face 项目:我的首个在线 SQL 查询工具之旅20241111

从零开始的 Hugging Face 项目&#xff1a;我的首个在线 SQL 查询工具之旅 作为一名 AI 初学者&#xff0c;我最近完成了一个意义非凡的项目&#xff1a;在 Hugging Face Spaces 上构建了一个简单却实用的在线 SQL 查询工具。这个项目不仅让我了解了 Hugging Face 平台的核心功…

Windows,虚拟机Ubuntu和开发板三者之间的NFS服务器搭建

Windows,虚拟机Ubuntu和开发板三者之间的NFS服务器搭建 &#xff08;1&#xff09;虚拟机 ubuntu 要使用桥接模式&#xff0c;不能使用其他模式 &#xff08;2&#xff09;通过网线将PC和开发板网口直连:这样的连接&#xff0c;开发板是无法连接外网的 &#xff08;3&#xff…

C语言第十一周课——函数的调用

目录 一、冒泡法排序 二、二分法查找 一、冒泡法排序 通过调用函数来实现冒泡法 #include<stdio.h> // 定义数组长度 #define SIZE 3 void bubbleSort(int arr[], int n);int main() {int arr[SIZE];int i;// 从控制台输入数字到数组printf("请输入%d个整数&#x…

C# 有趣的小程序—桌面精灵详细讲解

C# 桌面精灵详细讲解 最近写了一个简化版桌面精灵&#xff0c;效果如图所示&#xff0c;可以实现切换动画&#xff0c;说话、鼠标拖动&#xff0c;等功能。具体如何做&#xff0c;我发布了一个资源里面包含ppt详解、源代码以及动画素材。放心吧&#xff0c;免费的&#xff0c;…

【系统架构设计师】真题论文: 论软件可靠性设计与应用(包括解题思路和素材)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 真题题目(2009年 试题4)解题思路论文素材参考软件可靠性概念软件可靠性的重要意义影响软件可靠性的因素软件可靠性设计方法真题题目(2009年 试题4) 目前在企业中,以软件为核心的产品得到了广泛的应用。随着系…

如何开发查找附近地点的微信小程序

我开发的是找附近卫生间的小程序。 在现代城市生活中&#xff0c;找到一个干净、方便的公共卫生间有时可能是一个挑战。为了解决这个问题&#xff0c;我们可以开发一款微信小程序&#xff0c;帮助用户快速找到附近的卫生间。本文将介绍如何开发这样一款小程序&#xff0c;包…

视觉SLAM数学基础

本文系统梳理从相机成像模型&#xff0c;通过不同图像帧之间的构造几何约束求解位姿变换&#xff0c;再根据位姿变换和匹配点还原三维坐标的过程&#xff0c;可以作为基于特征点法的视觉SLAM的数学基础。 1、相机成像模型 1.1、针孔相机模型 实际相机的成像方式通常很复杂&a…

19.(开发工具篇mysql库)mysql锁表问题解决

1&#xff1a;查看锁表情况 show OPEN TABLES where In_use > 0; 2&#xff1a;查看所有进程命令 show processlist 3&#xff1a;杀对应进程&#xff08;通过host&#xff0c;db找对应的ID&#xff09; kill 57303

计算机新手练级攻略——如何搜索问题

目录 计算机学生新手练级攻略——如何搜索问题1.明确搜索意图2.使用精确关键词3.使用专业引擎搜索4.利用好技术社区1. Stack Overflow2. GitHub3. IEEE Xplore4. DBLP 5.使用代码搜索工具1. GitHub 代码搜索2. Stack Overflow 代码搜索3. Papers with Code4. IEEE Xplore 6.查阅…

51c自动驾驶~合集10

我自己的原文哦~ https://blog.51cto.com/whaosoft/11638131 #端到端任务 说起端到端&#xff0c;每个从业者可能都觉得会是下一代自动驾驶量产方案绕不开的点&#xff01;特斯拉率先吹响了方案更新的号角&#xff0c;无论是完全端到端&#xff0c;还是专注于planner的模型&a…

““和“*“:身怀绝技的双飞客

"&"和"*"是C语言里面的两个斜杠青年&#xff0c;不同的形式具有不同的作用。 一、"&"运算符 1&#xff0e;按位与运算符&#xff08;Bitwise AND operator&#xff09; 对两个操作数的每一位进行逐位比较&#xff0c;相应位都为1时&a…

大模型日报|6 篇必读的大模型论文

1.华为推出科学智能体 Agent K v1.0&#xff0c;已达 Kaggle 大师水平 在这项工作中&#xff0c;来自华为诺亚方舟实验室和伦敦大学学院的研究团队提出了 Agent K v1.0&#xff0c;它是一个端到端自主数据科学智能体&#xff08;agent&#xff09;&#xff0c;旨在对各种数据科…

Redis在docker中的主从,哨兵配置

主从配置 docker 中redis服务启动&#xff0c;将配置文件和数据挂载到 redisData中,记得先创建好redis.conf docker run -p 6379:6379 \--name redis \-v /root/redisData/data:/data \-v /root/redisData/conf/redis.conf:/etc/redis/redis.conf \-d redis redis-server /et…

游戏中的设计模式及杂项

概述 如果要做以下游戏功能会用到哪些设计模式。比如创建一个人物角色&#xff0c;这个角色可以装备刀&#xff0c;然后角色可以用刀砍怪物&#xff0c;造成流血。 对于这个游戏功能&#xff0c;可以使用以下设计模式&#xff1a; 工厂模式&#xff08;Factory Pattern&#x…

MySQL核心业务大表归档过程

记录一下2年前的MySQL大表的归档&#xff0c;当时刚到公司&#xff0c;发现MySQL的业务核心库&#xff0c;超过亿条的有7张表&#xff0c;最大的表有9亿多条&#xff0c;有37张表超过5百万条&#xff0c;部分表行数如下&#xff1a; 在测试的MySQL环境 &#xff1a; pt-archiv…

cache(二)直接缓存映射

在知乎发现一份不错得学习资料 请教CPU的cache中关于line,block,index等的理解&#xff1f; PPT 地址 https%3A//cs.slu.edu/%7Efritts/CSCI224_S15/schedule/chap6-cache-memory.pptx 课程主页 https://cs.slu.edu/~fritts/CSCI224_S15/schedule/ 0. 缓存定义 这张图展示了缓…

探索Apache Spark:现代数据处理的闪电利剑

在大数据技术的快速发展中&#xff0c;Apache Spark凭借其高效的内存计算和友好的编程模型&#xff0c;成为了现代数据处理领域中的一颗耀眼明星。Spark的出现填补了批处理和实时处理之间的空白&#xff0c;使得数据分析任务能够以前所未有的速度和效率得以执行。本文将深入剖析…

光流法(Optical Flow)

一、简介 光流法&#xff08;Optical Flow&#xff09;是一种用于检测图像序列中像素运动的计算机视觉技术。其基于以下假设&#xff1a; 1.亮度恒定性假设&#xff1a;物体在运动过程中&#xff0c;其像素值在不同帧中保持不变。 2.空间和时间上的连续性&#xff1a;相邻像素之…

软考中级-软件设计师 Python篇

文章目录 Python 基础语法Python 数据结构函数与模块面向对象编程常用算法实现文件操作异常处理常用库 Python 基础语法 变量与数据类型&#xff1a;Python支持多种数据类型&#xff0c;包括整数 (int)、浮点数 (float)、字符串 (str)、布尔值 (bool) 和复数 (complex)。 x …

打造自己的RAG解析大模型:(可商用)智能文档服务上线部署

通用版面分析介绍 版面解析是一种将文档图像转化为机器可读数据格式的技术&#xff0c;广泛应用于文档管理和信息提取等领域。通过结合OCR、图像处理和机器学习&#xff0c;版面解析能够识别文档中的文本块、图片、表格等版面元素&#xff0c;最终生成结构化数据&#xff0c;大…