【MySql】事务的原理


【MySql】事务的原理

  • 数据库的隔离级别原理
    • 读未提交
    • 读已提交
    • 可重复读(Repeatable Read)
    • 串行化(最高的隔离级别,强制事务串行执行,避免了所有并发问题)
    • MVCC(Multi-Version Concurrency Control多版本并发控制)
      • UNDO日志版本链(数据库原子性原理)
        • 介绍
        • UNDO的实现
      • Read View(一致性视图)
        • ***Read View的执行流程***
        • Read View的可见性规则
  • 数据库的一致性
  • 持久性
  • 事务的优化

事务:要么全部成功要么全部失败,目的是为了保证数据最终的一致性。

数据库的隔离级别原理

在事务并发执行时,他们内部的操作不能互相干扰,隔离 性由MySQL的各种锁以及MVCC机制来实现

先了解下面三个概念

  1. 脏读(Dirty Read)
    指一个事务读取到了另一个未提交事务修改的数据。
  2. 不可重复读(Non-Repeatable Read)
    指同一个事务内,两次读取同一数据时,结果不一致(因为中间被其他已提交事务修改 / 删除了)。
  3. 幻读(Phantom Read)
    指同一个事务内,两次执行相同的查询语句时,返回的结果集行数不一致(因为中间被其他已提交事务新增 / 删除了符合条件的记录)。
  4. 可重复读
    可重复读的核心目标是:保证同一事务内,多次读取同一数据时,结果始终一致,不受其他已提交事务的修改影响,从而避免 “不可重复读” 问题。
    例子:在这个事务执行的时候,InnoDB 会为该事务创建一个 一致性视图(Read View),他事务即使修改了数据并提交,只要当前事务没结束,就看不到这些修改(因为视图没变)。
  5. 脏写(Dirty Write)
    是指一个事务修改了另一个未提交事务已经修改过的数据。
    比如:事务 A 修改数据 X 为 100(未提交);
    事务 B 此时也修改数据 X 为 200(未提交);
    最终无论 A/B 是否提交,A 的修改都会被 B 覆盖(或反之),导致未提交的中间状态被直接覆盖。
    所以不建议在 Java 代码中先读取数据、在内存中计算(如做加法),再更新回数据库。这种方式在并发场景下很容易出现 “更新丢失” 问题,而应该尽量通过数据库层面的原子操作来实现。
优先用数据库原子操作(推荐)
示例:给用户余额加 100// 条件构造器:更新id=1的用户,balance = balance + 100
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", 1).setSql("balance = balance + 100"); // 直接在数据库层面计算// 执行更新(底层生成 SQL:UPDATE user SET balance = balance + 100 WHERE id = 1)
userMapper.update(null, updateWrapper);

读未提交

读未提交(Read Uncommitted)
最低的隔离级别,允许一个事务读取另一个未提交事务的数据
可能出现的问题:脏读、不可重复读、幻读
适用场景:对数据一致性要求极低,追求最高并发性能的场景

SET transaction_isolation = 'READ-UNCOMMITTED';
BEGIN;
select * from app_userw where id = 1;

使用读未提交事务进行修改

SET transaction_isolation = 'READ-UNCOMMITTED';-- 开启事务
BEGIN;-- 执行更新操作
UPDATE app_userw 
SET  age = 30 
WHERE id = 1;

我并没有提交更新但是读到的age已经被修改成了30这就是读未提交(READ UNCOMMITTED)
在这里插入图片描述
在这种情况下如果使用代码去读就会”脏读“。

读已提交

读已提交(Read Committed)
跟上面不一样的点则是如果未提交则不能被读
保证一个事务只能读取另一个已提交事务的数据
解决了脏读问题,但仍可能出现不可重复读和幻读
适用场景:大多数关系型数据库的默认隔离级别(如 SQL Server、Oracle),适用于对数据一致性有一定要求的场景

可重复读(Repeatable Read)

确保同一事务中多次读取同一数据的结果一致
解决了脏读和不可重复读问题,但仍可能出现幻读
适用场景:MySQL 的默认隔离级别,适用于需要保证数据可重复读取的场景
串行化(Serializable)
实现原理:
第一次查的时候都是查视图,除非使用了update等操作才会进行数据的更新,但是也仅限于更新的那条数据而已,其他的数据还是视图的数据。

串行化(最高的隔离级别,强制事务串行执行,避免了所有并发问题)

解决了脏读、不可重复读和幻读所有问题
适用场景:对数据一致性要求极高,但可以接受极低并发性能的场景

对事务操作的数据加锁(如表锁、行锁、范围锁),阻止其他事务同时修改或读取。例如,事务 A 操作某行数据时,其他事务必须等待 A 完成后才能操作。

MVCC(Multi-Version Concurrency Control多版本并发控制)

MVCC 通过 “版本链存储历史数据 + Read View 判断可见性” 的机制,巧妙地让读写操作并行执行,同时通过事务 ID 和可见性规则保证隔离性。

数据库事务是通过MVCC机制来实现的,其核心思想是通过UNDO保存数据的多个历史版本,让读写操作在不阻塞彼此的情况下并行执行,同时保证事务隔离性。

InnoDB 会为每个数据行自动添加三个隐藏列,用于版本管理:
DB_TRX_ID:记录最后一次修改该行数据的事务 ID(6 字节)。
DB_ROLL_PTR:回滚指针(7 字节),指向该行的上一个历史版本(存储在 undo 日志中)。
DB_ROW_ID:若表没有主键,InnoDB 会自动生成该列作为隐含主键(6 字节)。

UNDO日志版本链(数据库原子性原理)

介绍

UNDO 日志作为版本链的载体,不仅支撑了 MVCC,还为事务回滚提供了基础,是数据库高并发能力的核心技术之一。 记录事务对数据的修改操作(如插入、更新、删除)的反向操作,用于在事务回滚或需要读取历史版本时恢复数据。

若事务执行失败(如代码异常、数据库崩溃),数据库会通过 undo 日志反向执行所有操作,将数据恢复到事务开始前的状态,保证 “全不做”。
1.事务提交机制
事务只有在显式执行COMMIT时,所有修改才会被确认(持久化到磁盘);若执行ROLLBACK或异常终止,数据库直接根据 undo 日志回滚,确保 “全不做”。
2.崩溃恢复
数据库崩溃后重启时,会通过事务日志(如 InnoDB 的 redo log 和 undo log) 检查未完成的事务:对已提交的事务,确保修改生效;对未提交的事务,通过 undo 日志回滚,避免残留中间状态。

UNDO的实现

trx_id是事务的唯一id,roll_poiner是回滚指针,指向前一条数据,如果出现了问题就会通过这个回滚指针回滚到上一个版本,每个事务都是单独的,第一条事务的id就是他自己。
注意(begin/start transaction 命令并不是一个事务的起点,在执行到它们之后第一条执行的修改操作的InnoDB语句事务才真正的启动,才会像数据库申请事务id(trx_id),mysql内部是严格按照事务的启动顺序来分配id。)

每一次的修改就是把上一个的事务的事务id写到roll_poiner中并且在新增一个新的trx_id,不管事务有没有执行commit他都会存储在这个版本链里面
在这里插入图片描述

这种机制既保证了事务的原子性(要么全做,要么全不做),又为多版本并发控制提供了基础。

Read View(一致性视图)

Read View 是 MVCC 中判断数据版本可见性的依据。
他有4 个参数:

m_ids:当前未提交的活跃事务 ID 数组
min_trx_id:活跃事务中最小的 ID
max_trx_id:下一个要分配的事务 ID(未开始的事务)这是一个全局递增的计数器,用于为新事务分配唯一 ID。
creator_trx_id:当前事务自己的 ID

组成规则:
这个视图包含查询时所有未提交事务的 ID 数组,以及该数组中的最小事务 ID、已创建的最大事务 ID,同时还包括生成此视图的当前事务自身 ID,共同作为判断数据版本可见性的依据。

Read View的执行流程

在这里插入图片描述
图里事务 300 提交后执行查询,此时生成 Read View 时,会记录当前数据库里的活跃事务(也就是未提交的事务,比如图里的 100、200 ,因为 300 自己提交了,不算活跃了),用来决定查询能看到哪些版本的数据。
注意:
只要事务第一次需要读数据 ,InnoDB 就会给这个事务生成一个 Read View 。一旦生成,在可重复读(Repeatable Read)隔离级别 下,这个 Read View 会跟着事务走到底。

Read View的可见性规则

在可重复读隔离级别,当事务开启,执行任何查询sql时会生成当前事务的一致性视图read-view,该视图在事务结束之前都不会变化(如果是读已提交隔离级别在每次执行查询sql时都会重新生成),这个视图由执行查询时所有未提交事务id数组(数组里最小的id为min_id)和已创建的最大事务id(max_id)组成,事务里的任何sql查询结果需要从对应版本链(undo回滚日志)里的最新数据开始逐条跟read-view做比对从而得到最终的视图结果。
在这里插入图片描述
在读已提交的隔离级别中, Read View的读取规则是有变化的,在可重复读中只有第一次查询的 Read View视图会从表里面拿最新的数据而在读已提交的隔离级别中每一次查询都会去数据库中拿一份新的来生成一个 Read View最新的值是什么 Read View里面就是什么,底层和可重复读也是通过版本链来比对。

数据库的一致性

一致性是 ACID 的最终目标,其他三个特性(原子性、隔离性、持久性)以及业务代码正确逻辑来实现的。
原子性确保事务不残留中间状态;
隔离性避免并发事务相互干扰(如脏读导致的数据逻辑错误);
持久性确保已提交的合法状态不丢失。

持久性

一旦提交了事务,它对数据库的改变是永久性的,持久性由redo log日志来实现。

REDO LOG 称为重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性
这篇文章的介绍比较详细。
【MySql】数据库Redo日志介绍

事务的优化

事务优化原则
1.将查询等数据准备操作放到事务外
2.事务中避免远程调用,若必须进行远程调用则要设置超时,防止事务等待时间过久
3.事务中避免一次性处理太多数据,可以拆分成多个事务分次处理
4.更新等涉及加锁的操作尽可能放在事务靠后的位置
5.能异步处理的尽量异步处理
6.应用侧(业务代码)保证数据一致性,采用非事务方式执行(当业务逻辑相对简单时,可以不依赖数据库事务,而是通过 Java 等业务代码手动实现数据一致性保障)

最后避免大事务
在这里插入图片描述

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

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

相关文章

YOLO--目标检测基础

一、基本认知1.1目标检测的定义目标检测&#xff08;Object Detection&#xff09;&#xff1a;在图像或视频中检测出目标图像的位置&#xff0c;并进行分类和识别的相关任务。主要是解决图像是什么&#xff0c;在哪里的两个具体问题。1.2使用场景目标检测的使用场景众多&#…

GitLab 18.2 发布几十项与 DevSecOps 有关的功能,可升级体验【四】

沿袭我们的月度发布传统&#xff0c;极狐GitLab 发布了 18.2 版本&#xff0c;该版本带来了议题和任务的自定义工作流状态、新的合并请求主页、新的群组概览合规仪表盘、下载安全报告的 PDF 导出文件、中心化的安全策略管理&#xff08;Beta&#xff09;等几十个重点功能的改进…

Python----大模型(大模型微调--BitFit、Prompt Tuning、P-tuning、Prefix-tuning、LORA)

一、大模型微调 1.1、解释 微调(Fine-tuning)是在预训练大模型基础上&#xff0c;针对特定领域数据进行二次训练的技术过程。这一过程使大型语言模型(如GPT、BERT等)能够更好地适应具体应用场景&#xff0c;显著提升在专业领域的表现。 1.2、微调的基本流程 模型选择&#xf…

本地安装 SQLite 的详细步骤

方法 1:使用预编译二进制文件 下载 SQLite: 访问 SQLite 官方下载页面。 下载 Precompiled Binaries for Windows 中的 sqlite-tools-win32-x86-*.zip。 解压文件: 将下载的 ZIP 文件解压到一个目录(例如 C:\sqlite)。 配置环境变量: 右键「此电脑」→「属性」→ 左侧「高…

专题:2025医药生物行业趋势与投融资研究报告|附90+份报告PDF、原数据表汇总下载

原文链接&#xff1a;https://tecdat.cn/?p43444 圈内人都知道&#xff0c;2024年的BioChina展会现场&#xff0c;某跨国药企高管盯着融资展板喃喃自语&#xff1a;“去年A轮平均3.2亿&#xff0c;今年怎么降到2.1亿了&#xff1f;” 这个细节&#xff0c;恰是行业寒冬的缩影…

Chroma安装教程

Chroma 这里讲述的是windows环境 下载Chroma安装包 下载地址&#xff1a;https://github.com/chroma-core/chroma/releases 运行 chroma-windows.exe run --port 8000通过心跳检测访问是否正常 http://localhost:8000/api/v2/heartbeat快速使用 python安装chromadb pyth…

kali Linux 2025.2安装教程(解决安装失败-图文教程超详细)

一&#xff0c;下载镜像&#xff1a; 进入官网&#xff1a;Get Kali | Kali Linux &#xff0c;往下滑 等待两年半&#xff0c;镜像下载好。 二&#xff0c;虚拟机安装&#xff1a; 转&#xff1a;VMware Workstation Pro 17 安装图文教程 知乎平台&#xff1a;VMware Work…

uniapp项目使用ucharts实现折线图详细讲解(案例)

1.在Hbuildx里面的工具>插件安装&#xff0c;进入DCloud搜索uchart 2.点击对应的项目导入该插件 可以看到在该目录下有该插件 3.进入官网演示 - uCharts跨平台图表库&#xff0c;找一个示例代码测试一下&#xff0c;是否可以成功应用 因为这里使用的是vue2&#xff0c;如果你…

数据分析师进阶——95页零售相关数据分析【附全文阅读】

这份资料适合零售行业从业者&#xff0c;尤其是服装销售领域的人员&#xff0c;能帮大家用数据分析提升销售业绩。资料先提出 “店铺 20 问”&#xff0c;引导思考店铺运营问题&#xff0c;接着点明数据分析对提升销售、找出销售不佳原因的重要性 。详细介绍销售业绩相关公式及…

计算机组成原理(6) - 加法器

加法器是数字电路中用于执行加法运算的基本逻辑单元&#xff0c;广泛应用于计算机、计算器、数字信号处理器等电子设备中。它能将两个二进制数相加&#xff0c;并输出结果及可能产生的进位。一、加法器的基本功能加法器的基本功能是在数字电路中对输入的二进制数执行加法运算&a…

Qt 与 WebService 交互开发

在现代软件开发中&#xff0c;WebService 已成为实现跨平台、跨语言通信的重要标准。Qt 作为一个强大的跨平台框架&#xff0c;提供了完善的工具和类库来实现与 WebService 的交互。本文将深入探讨 Qt 与 WebService 交互开发的核心技术和实践经验&#xff0c;包括 SOAP 协议实…

LLM 模型部署难题的技术突破:从轻量化到分布式推理的全栈解决方案

大语言模型(LLM)的部署一直是工业落地的核心挑战。动辄百亿甚至万亿参数的模型规模,对硬件资源、推理速度和系统稳定性提出了严苛要求。本文将系统剖析 LLM 部署中的关键技术瓶颈,从模型压缩、推理加速到分布式架构设计,提供可落地的工程化解决方案,并附具体实现代码。 …

理解训练深度前馈神经网络的困难—— 解锁深度学习的关键钥匙

2010年&#xff0c;深度学习先驱 Xavier Glorot 和 Yoshua Bengio 发表了这篇里程碑式的论文。它精准地诊断了当时阻碍深度神经网络发展的核心顽疾——**梯度消失/爆炸问题**&#xff0c;并开出了革命性的“药方”&#xff1a;**Xavier/Glorot 初始化**。这篇论文扫清了训练深度…

Objective-c 初阶——异常处理(try-catch)

一、try/catch/throw/finally 执行顺序 void doSomething() {NSAutoreleasePool *pool [[NSAutoreleasePool alloc] init];try {// 这一步抛异常[self riskyMethod]; } catch (NSException *e) {throw; // 把异常继续往上抛} finally {// ❗ 注意&#xff1a;这里的 finally…

计算机网络:(十二)传输层(上)运输层协议概述

计算机网络&#xff1a;&#xff08;十一&#xff09;多协议标记交换 MPLS前言一、运输层的作用二、基于端口的复用和分用功能三、屏蔽作用四、可靠信道与不可靠信道五、运输层的两个主要协议前言 前面我们讲解了计算机网络中网络层的相关知识&#xff0c;包括网络层转发分组的…

一场关于电商零售增长破局的深圳探索

“电商AI&#xff0c;不再是选择题”2025年&#xff0c;电商行业正面临流量成本攀升、用户留存率下降、供应链协同效率低等核心困境&#xff0c;传统数字化工具已难以满足精细化运营需求。在此背景下&#xff0c;百度智能云正加速布局电商领域&#xff0c;为零售企业提供从基础…

当非洲爱上“中国制造”:如何赢在起跑线

非洲大陆的消费浪潮正以前所未有的速度奔涌。2025年前五个月&#xff0c;中非贸易额同比暴涨12.4%&#xff0c;创下历史新高。在这片拥有14亿人口的土地上&#xff0c;60%是30岁以下的年轻人&#xff0c;城镇化浪潮席卷、中产阶级快速崛起&#xff0c;从家电、汽车到建材、电子…

vLLM(3)vllm在线启动集成openweb-ui

文章目录**步骤 1: 启动 vLLM 服务****方式 1: 直接命令行启动****方式 2: Docker 启动****步骤 2: 配置 Open WebUI 连接 vLLM****方法 1: 修改 Open WebUI 环境变量****方法 2: 通过 docker-compose.yml 部署****步骤 3: 在 Open WebUI 中添加模型****验证是否成功****常见问…

Python----大模型(基于Agent的私人AI助理项目)

开发一个智能的问答系统&#xff0c;该系统支持用户聊天&#xff0c;传输文件。通过自然语言处理技术&#xff0c;机器人能够理解用户的意图。机器人将利用互联网搜索引擎来补充信息&#xff0c;确保用户能够获得全面且准确的回答。 一、web ui界面 我们采用gradio来编写的ui界…

Python爬虫实战:研究scrapely库相关技术构建电商数据提取系统

1. 引言 在当今数字化时代,网络上蕴含着海量的有价值信息。如何从这些非结构化的网页中自动提取出结构化的数据,成为了数据挖掘和信息检索领域的重要研究课题。网络爬虫作为一种自动获取网页内容的技术,被广泛应用于信息收集、数据分析等领域。然而,网页结构的多样性和复杂…