深度解析 MySQL 事务、隔离级别和 MVCC 机制:构建高效并发的数据交响乐(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: 深度解析 MySQL 事务、隔离级别和 MVCC 机制:构建高效并发的数据交响乐

前言

MySQL 事务是比较重要且核心的一部分,在操作数据库 DML 语句时,以及开源框架基于 MySQL 进行事务操作时,保持事务的 ACID 特性是数据可靠的一大保障

事务特性

原子性(Atomicity)

一个事务必须被视为不可分割的最小单元,事务的所有操作要么全部提交成功、要么全部提交失败,对于一整个事务来说,不能只执行其中的一部分操作,例如:A 转账给 B,A 余额必须减少,B 余额必须增加

一致性(Consistency)

事务从一种状态扭转到另外一种状态,在事务开始前、结束后,数据的完整性没有被破坏

例如:A、B 事务操作前的总额是多少,转账后,事务操作后的总额也应该是一样的

隔离性(Isolation)

事务的执行不能被其他事务执行所干扰,即一个事务的执行应该与其他并发执行的事务是相互隔离的

持久性(Durability)

一旦事务被提交,对其所做的任何信息变更,都应该永久持久化到数据库中,即使系统瘫痪,已提交的数据也不会丢失

事务并发引发的问题

MySQL 基于客户端 / 服务器架构的软件,对于同一个服务器来说,可以有若干个客户端与之连接,每个客户端与服务器连接之后,就可以称之为一个会话 Session;每个客户端都可以在开启的会话中向 MySQL 服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就是对于服务器来说,可以同时处理多个事务

MySQL 四大事务特性中 > 隔离性,理论上在某个事务在对数据进行访问或 DML 操作时,其他事务应该进行排队,当该事务提交之后,其他事务才可以继续访问此数据,这样的话,由并发事务执行就转变为了串行化执行;串行化执行方式对性能影响太大,既想保持事务的隔离性,又想让服务器在处理同一数据 > 多事务时性能尽量高些,从而会为我们带来以下数据问题:脏读、不可重复读、幻读.

脏读

当一个事务读取到了另外一个事务修改但未提交的数据,称之为脏读

如上图,在事务 A 执行过程中,事务 A 对数据资源进行了修改,事务 B 读取到了事务 A 修改后的数据;可能由于某些原因,导致事务 A 没完成提交,发生了 Rollback 操作,则事务 B 读取到的数据就是脏数据

这种读取到另外一个事务未提交的数据的现象称为脏读(DD)

不可重复读

当在一个事务内的记录被检索过两次,若两次得到的结果不同,此现象称为不可重复读

事务 B 读取了两次数据,在第一次读取完准备读第二次期间,事务 A 修改了数据,导致事务 B 在第二次读出来的数据与第一次是不一致的.

幻读

在事务执行过程中,另外一个事务新增或删除了记录,正在读取记录的事务,会发生幻读.

事务 B 在前后两次读取同一个范围内的数据,在第一次读取完准备读第二次期间,事务 A 新增或删除了数据,导致事务 B 后一次读取到前一次未统计到的行数

幻读、不可重复读有些类似,但幻读重点强调了读取到了之前没有获取到的记录

隔离级别

SQL 标准中规定了四种隔离级别:未提交读、已提交读、可重复读、可串行化读,但不同数据库厂商对 SQL 标准规定的四种隔离级别支持不一样,比如:Oracle 只支持已提交读、可串行化读两种隔离级别,MySQL 同 SQL 标准一样支持四种隔离级别,但与其不同的是,MySQL 在可重复读隔离级别下,是一大程度下是可以避免幻读问题发生的.

隔离级别 脏读 不可重复读 幻读
未提交读
READ UNCOMMITTED
可能 可能 可能
已提交读
READ COMMITTED
可能 可能
可重复读
REPEATABLE READ
SQL 标准可能
MySQL 少数场景会发生
可串行化
SERIALIZABLE

MySQL 默认隔离级别:REPEATABLE READ,可以手动修改事务的隔离级别

如何更改事务隔离级别

通过下面的语句可以更改事务的隔离级别:

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL level;

level 可选值有四个:REPEATABLE READ、READ COMMITTED、READ UNCOMMITTED、SERIALIZABLE

设置事务的隔离级别语句中,在 SET 关键字后面可以放置 GLOBAL 关键字、SESSION 关键字,这样会对不同范围的事务产生不同的影响,具体如下:

  1. 使用 GLOBAL 关键字,在全局范围内生效
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

对执行完该语句之后产生的会话起作用,当前已经存在的会话无效

  1. 使用 SESSION 关键字,在当前会话范围内生效
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

对当前会话的所有后续事务生效,该语句可以在已经开启的事务中执行,但不会影响当前正在执行的事务

  1. GLOBAL、SESSION 两者都不使用,那么只会执行语句的下一个事务产生影响
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

对当前会话中下一个即将开启的事务有效,下一个事务执行完以后,将会恢复到默认的隔离级别,该语句不能在已经开启事务中间执行,会报错 Transaction characteristics can't be changed while a transaction is in progress

  1. 若想在服务器启动时想改变事务的默认隔离级别,可以修改启动参数 transaction-isolation 值,比如:在启动服务器时指定了 --transaction-isolation=SERIABLIZABLE,那么事务的默认隔离级别就会从原来的 REPEATABLE READ -> SERIABLIZABLE

查看当前会话默认隔离级别可以通过查看系统变量 transaction_isolation 值或 SELECT @@transaction_isolation 来确定

mysql> SHOW VARIABLES LIKE 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
mysql> SELECT @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+

注意:transaction_isolation 系统变量是在MySQL 5.7.20 版本中引入来替换 tx_isolation 的,若你使用的还是之前版本,请将上述用到系统变量 transaction_isolation 地方替换为 tx_isolation

事务基本操作

事务开始:begin、start transaction(推荐)、begin work

事务回滚:rollback

事务提交:commit

事务保存点:savepoint

回滚保存点:ROLLBACK TO [SAVEPOINT] 保存点名称;

在我们进行事务操作时,操作了不同的 DML 语句,可以基于不同的语句作 savepoint

比如:插入 A 数据,执行 savepoint a、更新 B 数据,执行 savepoint b、删除 C 数据,执行 savepoint c

此时,若想取消删除 C 数据这个步骤,可以执行:ROLLBACK TO c; RELEASE SAVEPOINT c;

隐式提交:是否开启隐式提交 > 取决于 autocommit ON 开或 OFF 关

当使用 START TRANSACTION 或 BEGIN 语句开启了一个事务,或者把系统变量 autocommit 值设置为 OFF 时,事务就不会进行自动提交,但是如果我们输入了某些语句之后就会悄悄的提交掉,就像我们输入了 COMMIT 语句了一样,这种因为某些特殊的语句而导致事务提交的情况称为隐式提交

会导致事务隐式提交的语句包括,如下:

  1. 执行 DDL 语句 > create、alter、drop,当执行这些语句时,就会隐式提交前面 SQL 语句所属的事务.

  2. 更新 MySQL 数据库表信息:使用 ALTER USER、CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD 等语句时也会隐式的提交前边语句所属于的事务
  3. 事务控制或关于锁定的语句:在一个会话中,一个事务还未提交或回滚,又使用 START TRANSACTION 或 BEGIN 语句开启了一个事务,会隐式提交上一个事务;或者使用了 LOCK TABLES、UNLOCK TABLES 等关于锁定的语句也会隐式提交前面语句所属的事务
  4. 加载数据语句:使用 LOAD DATA 语句来批量往数据库导入数据时,也会隐式提交前面语句所属的事务
  5. 其他语句:START SLAVE、STOP SLAVE、RESET SLAVE、ANALYZE TABLE、CACHE INDEX、CHECK TABLE、FLUSH 等语句也会隐式提交前面语句所属的事务


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
4月前
|
存储 SQL 关系型数据库
MySQL中binlog、redolog与undolog的不同之处解析
每个都扮演回答回溯与错误修正机构角色: BinLog像历史记载员详细记载每件大大小小事件; RedoLog则像紧急救援队伍遇见突發情況追踪最后活动轨迹尽力补救; UndoLog就类似时间机器可倒带历史让一切归位原始样貌同时兼具平行宇宙观察能让多人同时看见各自期望看见历程而互不干扰.
234 9
|
5月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
141 2
|
5月前
|
存储 SQL 关系型数据库
MySQL 核心知识与性能优化全解析
我整理的这份内容涵盖了 MySQL 诸多核心知识。包括查询语句的书写与执行顺序,多表查询的连接方式及内、外连接的区别。还讲了 CHAR 和 VARCHAR 的差异,索引的类型、底层结构、聚簇与非聚簇之分,以及回表查询、覆盖索引、左前缀原则和索引失效情形,还有建索引的取舍。对比了 MyISAM 和 InnoDB 存储引擎的不同,提及性能优化的多方面方法,以及超大分页处理、慢查询定位与分析等,最后提到了锁和分库分表可参考相关资料。
135 0
|
6月前
|
关系型数据库 MySQL
MySQL字符串拼接方法全解析
本文介绍了四种常用的字符串处理函数及其用法。方法一:CONCAT,用于基础拼接,参数含NULL时返回NULL;方法二:CONCAT_WS,带分隔符拼接,自动忽略NULL值;方法三:GROUP_CONCAT,适用于分组拼接,支持去重、排序和自定义分隔符;方法四:算术运算符拼接,仅适用于数值类型,字符串会尝试转为数值处理。通过示例展示了各函数的特点与应用场景。
|
8月前
|
SQL 运维 关系型数据库
MySQL Binlog 日志查看方法及查看内容解析
本文介绍了 MySQL 的 Binlog(二进制日志)功能及其使用方法。Binlog 记录了数据库的所有数据变更操作,如 INSERT、UPDATE 和 DELETE,对数据恢复、主从复制和审计至关重要。文章详细说明了如何开启 Binlog 功能、查看当前日志文件及内容,并解析了常见的事件类型,包括 Format_desc、Query、Table_map、Write_rows、Update_rows 和 Delete_rows 等,帮助用户掌握数据库变化历史,提升维护和排障能力。
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
361 2
|
9月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
882 29
|
9月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
360 4
|
9月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
9月前
|
移动开发 前端开发 JavaScript
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。

推荐镜像

更多