MySQL - 并发事务问题及解决方案

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL - 并发事务问题及解决方案

20200810202125209.png

生猛干货

带你搞定MySQL实战,轻松对应海量业务处理及高并发需求,从容应对大场面试


Pre

MySQL - 多版本控制 MVCC 机制初探

中我们初步了解了 MVCC 的原理及其实现。 随着数据库并发事务处理能力的增强,数据库资源的利用率也会大大提高,从而提高了数据库系统的事务吞吐量,可以支持更多的用户并发访问。

但并发事务处理也会带来一些问题,如:脏读、不可重复读、幻读等等


脏读


一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象的叫作"脏读"(Dirty Reads)。


简答来说,读取了其他事务未提交的数据


不可重复读


一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫作“ 不可重复读”(Non-Repeatable Reads)。


幻读


一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”(Phantom Reads)。


Solutions


MySQL 数据库是通过事务隔离级别来解决上述问题的。

202008102033289.png


我们举例说明“脏读”和“不可重复读”的问题


【 RC 隔离级别】

MySQL 中默认的事务隔离级别是 RR,这里设置成 RC 隔离级别,此时提交事务 B 修改 id=1 的数据之后,事务 A 进行同样的查询操作,后一次和前一次的查询结果不一样,这就是不可重复读(重新读取产生的结果不一样了)。这里事务 A 读到了事务 B 提交的数据,即是“脏读”。


20200810204612432.png


【RR隔离级别】

下面我们来看看在mysql默认的RR隔离级别下的情况。当 teacher_id=1时,事务 A 先进行一次读取操作,事务 B 中间修改了 id=1 的数据并提交,事务 C 也插入了一条数据并提交。事务 A 第二次读到的数据和第一次完全相同。所以说它是可重读的。


20200810204657321.png



【幻读】

行锁可以防止不同事务版本的数据在修改提交时造成数据冲突的情况。但如何避免别的事务插入数据造成的问题呢。我们先来看看在 RC 隔离级别下的处理过程。

如下图所示,事务 A 修改了所有 teacher_id=30 的数据,但是当事务 B INSERT 新数据后,事务 A 发现莫名其妙的多了一行 teacher_id=30 的数据, 而且没有被之前的 UPDATE语句所修改,这就是“当前读”的幻读问题。


20200810204816289.png

跟上面的例子一样,也是在 RC 事务隔离级别下,这时事务 B INSERT 了一条数据,并提交,而事务 A 读到了事务 B 新插入的数据。这也是幻读,如下图所示。



20200810204842838.png


这里就需要重点注意不可重复读和幻读的区别了。前面讲了它们的含义,这个提醒大家的是:不可重复读重点在于 UPDATA 和 DELETE,而幻读的重点在于 INSERT。它们之间最大的区别是如何通过锁机制来解决它们产生的问题。这里说的锁只是使用悲观锁机制。


那么在 RR 隔离级别下,事务 A 在 UPDATE 后加锁,事务 B 无法插入新数据,这样事务 A在 UPDATE 前后读的数据保持一致,避免了幻读。


跟上面的案例一样,也是在 RR 事务隔离级别下,事务 A 在 UPDATE 后加锁,对于其他两个事务,事务 B 和事务 C 的 INSERT 操作,就必须等事务 A 提交后,才能继续执行。这里就用到了“锁”,这里使用的是 Gap 锁,后面会详细讲解。它和上面的情况一样,解决了“幻读”的发生,如下图所示。


2020081020491885.png



搞定MySQL


https://artisan.blog.csdn.net/article/details/107921219?spm=1001.2014.3001.5502




相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
SQL 存储 关系型数据库
MySQL索引及事务
MySQL索引及事务
16 2
|
5天前
|
存储 算法 关系型数据库
MySQL事务与锁,看这一篇就够了!
MySQL事务与锁,看这一篇就够了!
|
5天前
|
Java 关系型数据库 MySQL
MySQL 索引事务
MySQL 索引事务
13 0
|
6天前
|
运维 负载均衡 关系型数据库
MySQL高可用解决方案演进:从主从复制到InnoDB Cluster架构
MySQL高可用解决方案演进:从主从复制到InnoDB Cluster架构
|
13天前
|
SQL 安全 关系型数据库
【Mysql-12】一文解读【事务】-【基本操作/四大特性/并发事务问题/事务隔离级别】
【Mysql-12】一文解读【事务】-【基本操作/四大特性/并发事务问题/事务隔离级别】
|
15天前
|
存储 关系型数据库 MySQL
Mysql学习--深入探究索引和事务的重点要点与考点
Mysql学习--深入探究索引和事务的重点要点与考点
|
4天前
|
关系型数据库 MySQL 数据库
docker MySQL删除数据库时的错误(errno: 39)
docker MySQL删除数据库时的错误(errno: 39)
14 0
|
2天前
|
关系型数据库 MySQL 数据库
mysql 设置环境变量与未设置环境变量连接数据库的区别
设置与未设置MySQL环境变量在连接数据库时主要区别在于命令输入方式和系统便捷性。设置环境变量后,可直接使用`mysql -u 用户名 -p`命令连接,而无需指定完整路径,提升便利性和灵活性。未设置时,需输入完整路径如`C:\Program Files\MySQL\...`,操作繁琐且易错。为提高效率和减少错误,推荐安装后设置环境变量。[查看视频讲解](https://www.bilibili.com/video/BV1vH4y137HC/)。
20 3
mysql 设置环境变量与未设置环境变量连接数据库的区别
|
4天前
|
关系型数据库 MySQL 数据库连接
用Navicat备份Mysql演示系统数据库的时候出:Too Many Connections
用Navicat备份Mysql演示系统数据库的时候出:Too Many Connections
16 0
|
5天前
|
存储 Oracle 关系型数据库
oracle 数据库 迁移 mysql数据库
将 Oracle 数据库迁移到 MySQL 是一项复杂的任务,因为这两种数据库管理系统具有不同的架构、语法和功能。
16 0