《MySQL 事务深度解析:从 ACID 到实战,守住数据一致性的最后防线》

《MySQL 事务深度解析:从 ACID 到实战,守住数据一致性的最后防线》
前引:数据是业务的核心,而事务是数据可靠性的 “守护神”。在 MySQL 中,事务看似简单的 “提交 / 回滚” 操作,背后藏着 ACID 特性的严格约束、隔离级别的底层实现,以及并发场景下的锁竞争逻辑。很多开发者因为一知半解,导致系统出现脏读、幻读、数据丢失等严重问题。今天,我们就来层层拆解 MySQL 事务,让你从 “会用” 到 “精通”,真正守住数据一致性的底线!

目录

【一】事务介绍

【二】为什么要有事务

【三】事务的版本支持

【四】事务提交的两种方式

【五】事务的几种操作

(1)开始一个事务

(2)创建一个保存点

(3)回滚到指定保存点

(4)正常结束一个事务

(5)异常结束一个事务

【六】事务隔离级别

【七】事务相关结论

【八】修改事务隔离级别

【九】客户端会话与事务关系

【十】进阶:数据并发的场景

读-写


【一】事务介绍

事务是一组DML相关的语句(操作指令)集合,这些指令要么成功/不成功,满足如下性质:

原子性(Atomicity):操作不可分割,要么全成要么全败一致性(Consistency):事务前后数据库完整性不被破坏隔离性(Isolation):并发事务互不干扰,避免脏读、幻读等问题持久性(Durability):事务提交后,数据修改永久有效

【二】为什么要有事务

事务是为了服务应用层而存在,数据库是存储数据的地方,那么应用层对数据进行的操作就必须保障数据的一致性,这些关心事情(比如我这次的修改数据会不会不成功、等下有没有可能就没有了)应该人性化的交给MySQL自己实现,因此它是一个服务机制(为应用层服务)

【三】事务的版本支持

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持

mysql> show engines;           -- 表格显示 mysql> show engines \G         -- 行显示

【四】事务提交的两种方式

事务的提交方式常见的有两种: 自动提交 和 手动提交

查看事务提交方式:

show variables like 'autocommit';

用 SET 来改变 MySQL 的自动提交模式:

SET AUTOCOMMIT=0;            #SET AUTOCOMMIT=0 禁止自动提交 SET AUTOCOMMIT=1;           #SET AUTOCOMMIT=1 开启自动提交 

【五】事务的几种操作

(1)开始一个事务
begin;
(2)创建一个保存点
savepoint 自命名;
(3)回滚到指定保存点
rollback to 保存点名字;
(4)正常结束一个事务

注意:正常结束一个事务后,不支持回滚

commit;
(5)异常结束一个事务

注意:异常结束自动回滚,由于原子性,自动回到事务未提交时的数据状态

Aborted;

【六】事务隔离级别

(1)读未提交:在该隔离级别,所有的事务都可以看到其他事务没有提交的 执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多 并发问题,如脏读,幻读,不可重复读等!

理解:假设多个客户端并发访问操作同一个数据,单个客户端的任何操作不管提交与否,其它人都看的到

总结:不管对方提交与否,都看得到数据的修改

(2)读提交:该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默 认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select, 可能得到不同的结果!

理解:假设A在操作一个事务,B也在操作一个事务

A和B都在修改表1,A在执行commit之前,B是看不到A做出的修改的

一但A做出了提交,B就可以看到A的修改

总结:只要对方提交了,哪怕是多个事务,数据修改就会被其它人看到

(3)可重复读:这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是会有幻读问题!

理解:假设A在操作一个事务,B也在操作一个事务

A和B如果操作同一个表,此时A完成了提交,B是看不到修改的,B看到的是B进入该事务开始时的数据,如果A退出事务了,那么B的数据就会更新到最新的

总结:只有单方提交且退出事务,对方才看得到更改

什么是幻读?假设A修改了张三的年龄,然后提交退出事务,B此时可能在筛选年龄时出现两个张三,因为A提交且退出事务了,B就会更新数据

(4)串行化:这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突, 从而解决了幻读的问题。它在每个读的数据行上面加上共享锁!

总结:一把锁,你访问数据是没有问题的,当你修改数据时,只有在你前一个事务修改完了你才可以执行修改的操作,即串行化,唯一就是效率低

【七】事务相关结论

(1)持久化保障:只要开始一个事务,输入begin或者start transaction,事务便必须要通过                   commit提交,才会持久化,与是否设置自动提交无关

(2)事务可以手动回滚,同时,当操作异常,MySQL会自动回滚

以上可以看出事务的原子性和持久性:要么成功要么不成功,数据一经提交,就是持久化

而原子性保障了数据的一致性,

【八】修改事务隔离级别

  • 读未提交SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
  • 读提交SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • 可重复读(默认):SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
  • 串行化SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

【九】客户端会话与事务关系

客户端会话并非是一个事务,一个客户端中可以允许多个事务,事务之前相互独立

【十】进阶:数据并发的场景

数据并发场景有以下三种:

读-读 :不存在任何问题,也不需要并发控制

读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读

写-写 :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

什么是读and读?读写、写写就自然明白了

多个用户访问同一块数据不存在安全问题,因为只访问不修改

读-写

用来解决读-写的方案:多版本并发控制( MVCC )(无锁并发控制)

解决问题:读写互不阻塞

如何解决?超易懂版本

MVCC依靠三个工具:

(1)数据的额外三个标签:最近修改的事务ID、回滚指针、隐式主键

(2)快照仓库(针对写操作):当修改数据时会保存一份原始数据在 undo 日志里面,回滚指针                                                       指向该原始数据

(3)读视图(针对读操作):形成读视图,给当前事务划分可见范围,看不到未提交的或者在你                                                   后面提交的数据版本

运行过程:当A去修改数据时,会加行锁(保证修改的原子性),先将原始数据放在 undo 仓库,如果有读端访问,访问的是 undo 仓库里面的,看不到A的修改,因为有视图范围,读写可以同时进行,视图通过划分范围可以自行屏蔽脏读——四种隔离性无非是对这三个工具“度”的把控

Read more

《Web 自动化测试入门:从概念到百度搜索实战全拆解》

《Web 自动化测试入门:从概念到百度搜索实战全拆解》

一、自动化的核心概念 1. 定义:通过自动方式替代人工操作完成任务,生活中常见案例(自动洒水机、自动洗手液、超市闸机)体现了 “减少人力消耗、提升效率 / 质量” 的特点。 2. 软件自动化测试的核心目的: * 用于回归测试:软件迭代新版本时,验证新增功能是否影响历史功能的正常运行。 3. 常见面试题解析: * 自动化测试不能完全取代人工测试:需人工编写脚本,且功能变更后需维护更新,可靠性未必优于人工。 * 自动化测试不能 “大幅度降低工作量”:仅能 “一定程度” 减少重复工作,需注意表述的严谨性。 二、自动化测试的分类 自动化是统称,包含多种类型,核心分类及说明如下: 分类说明接口自动化针对软件接口的测试,目的是验证接口的功能、性能、稳定性等。UI 自动化 针对软件界面的测试,包含: 1. 移动端自动化:通过模拟器在电脑上编写脚本,测试手机应用;稳定性较差(受设备、

By Ne0inhk

Flutter 三方库 dart_webrtc 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、基于 WebRTC 标准的工业级实时音视频通讯与低延迟流媒体引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 dart_webrtc 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、基于 WebRTC 标准的工业级实时音视频通讯与低延迟流媒体引擎 在鸿蒙(OpenHarmony)系统的跨端视频会议、分布式安防监控、直播连麦或者是需要实现“端到端(P2P)”低延迟数据传输的场景中,如何通过一套 Dart 代码调用底层浏览器级的 WebRTC 算力?dart_webrtc 为开发者提供了一套工业级的、针对 Web 平台(JS 接口)进行高度封装的 WebRTC 适配方案。本文将深入实战其在鸿蒙 Web 入口应用中的音视频能力扩展。 前言 什么是 Dart WebRTC?它不仅是一个简单的。管理过程。由于由接口包装。

By Ne0inhk
WebGIS视角:体感温度实证,哪座“火炉”火力全开?

WebGIS视角:体感温度实证,哪座“火炉”火力全开?

目录 前言 一、火炉城市空间分布及特点 1、空间分布 2、气候特点 二、数据来源及技术实现 1、数据来源介绍 2、技术路线简介 三、WebGIS系统实现 1、后端设计与实现 2、前端程序实现 四、成果展示 1、整体展示 2、蒸烤模式城市 3、舒适城市 五、总结 前言         “火炉城市”是中国对夏季天气酷热的城市的夸张称呼。这一说法最早出现在民国时期,当时媒体有“三大火炉”之说,即重庆、武汉和南京,都是长江沿线的著名大城市,分别居于长江的上、中、下游,因夏季气温炎热,被媒体夸张地称为“火炉”。新中国成立后,又有了“四大火炉”之说,

By Ne0inhk

从前端到后端:新手如何高效完成一个全栈毕业设计项目

最近在帮学弟学妹们看毕业设计,发现一个普遍现象:很多同学的项目想法不错,但一涉及到前后端结合,就变得手忙脚乱。要么是前端写死了假数据,后端接口对不上;要么是代码结构混乱,自己过两天都看不懂。今天,我就结合一个常见的“校园二手交易平台”场景,分享一下新手如何高效、清晰地完成一个全栈毕业设计项目,希望能帮你避开那些常见的“坑”。 1. 新手常踩的坑:从混乱到清晰 在开始动手写代码之前,我们先看看哪些地方容易出问题。理解这些,能让你少走很多弯路。 1. 前后端高度耦合:这是最常见的错误。比如,前端页面里直接写死了后端服务器的IP和端口,或者把业务逻辑判断(如用户角色)硬编码在前端。一旦后端地址变更或逻辑调整,前端就得大改。正确的做法是前后端完全分离,通过定义良好的API接口进行通信,前端只关心数据展示和交互,后端只负责数据处理和业务逻辑。 2. 缺乏API文档或接口约定:前端和后端同学(或者就是你自己)口头约定了一下接口格式,开发过程中一变再变,导致联调时互相“扯皮”。一个简单的 api-docs.md 文件或者使用

By Ne0inhk