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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 深度解析 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 等语句也会隐式提交前面语句所属的事务


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
19天前
|
存储 关系型数据库 MySQL
MySQL MVCC全面解读:掌握并发控制的核心机制
【10月更文挑战第15天】 在数据库管理系统中,MySQL的InnoDB存储引擎采用了一种称为MVCC(Multi-Version Concurrency Control,多版本并发控制)的技术来处理事务的并发访问。MVCC不仅提高了数据库的并发性能,还保证了事务的隔离性。本文将深入探讨MySQL中的MVCC机制,为你在面试中遇到的相关问题提供全面的解答。
55 2
|
6天前
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
21 3
|
7天前
|
存储 关系型数据库 MySQL
MySQL 字段类型深度解析:VARCHAR(50) 与 VARCHAR(500) 的差异
在MySQL数据库中,`VARCHAR`类型是一种非常灵活的字符串存储类型,它允许存储可变长度的字符串。然而,`VARCHAR(50)`和`VARCHAR(500)`之间的差异不仅仅是长度的不同,它们在存储效率、性能和使用场景上也有所不同。本文将深入探讨这两种字段类型的区别及其对数据库设计的影响。
17 2
|
11天前
|
存储 关系型数据库 MySQL
PHP与MySQL动态网站开发深度解析####
本文作为技术性文章,深入探讨了PHP与MySQL结合在动态网站开发中的应用实践,从环境搭建到具体案例实现,旨在为开发者提供一套详尽的实战指南。不同于常规摘要仅概述内容,本文将以“手把手”的教学方式,引导读者逐步构建一个功能完备的动态网站,涵盖前端用户界面设计、后端逻辑处理及数据库高效管理等关键环节,确保读者能够全面掌握PHP与MySQL在动态网站开发中的精髓。 ####
|
19天前
|
存储 关系型数据库 MySQL
MySQL MVCC深度解析:掌握并发控制的艺术
【10月更文挑战第23天】 在数据库领域,MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种重要的并发控制机制,它允许多个事务并发执行而不产生冲突。MySQL作为广泛使用的数据库系统,其InnoDB存储引擎就采用了MVCC来处理事务。本文将深入探讨MySQL中的MVCC机制,帮助你在面试中自信应对相关问题。
56 3
|
19天前
|
缓存 关系型数据库 MySQL
MySQL执行计划深度解析:如何做出最优选择
【10月更文挑战第23天】 在数据库查询性能优化中,执行计划的选择至关重要。MySQL通过查询优化器来生成执行计划,但有时不同的执行计划会导致性能差异。理解如何选择合适的执行计划,以及为什么某些计划更优,对于数据库管理员和开发者来说是一项必备技能。
28 2
|
20天前
|
存储 运维 监控
运维技术深度解析:构建高效、稳定的运维体系
【10月更文挑战第22天】运维技术深度解析:构建高效、稳定的运维体系
99 0
|
20天前
|
人工智能 运维 监控
运维技术深度解析:构建高效、稳定的IT基础设施
【10月更文挑战第22天】运维技术深度解析:构建高效、稳定的IT基础设施
43 0
|
20天前
|
机器学习/深度学习 边缘计算 运维
运维技术深度解析:构建高效、稳定的IT基础设施
【10月更文挑战第22天】运维技术深度解析:构建高效、稳定的IT基础设施
36 0
|
8天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
22 4

推荐镜像

更多