MySQL 下事务的四种隔离级别|学习笔记

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 快速学习 MySQL 下事务的四种隔离级别

开发者学堂课程【MySQL 实操课程MySQL 下事务的四种隔离级别】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/717/detail/12816


MySQL 下事务的四种隔离级别

 

目录:

一、事务的隔离级别

二、MySQL 下事务的四种隔离级别

三、查看事务的隔离级别

四、演示实例

五、回顾

 

一、事务的隔离级别

1、原生 MySQL 和 RDS for MySQL 的默认事务隔离级别不一样。

(1)查看 RDS 的默认事务隔离级别

mysql> show variables like tx_isolation' ;

图片1.png

可看到事务隔离级别为 READ-COMMITTED,读已提交

(2)查看自主安装的 mysql 的默认事务级别

新增一个 cloudshell,编辑:

shell@Alicloud:~S /usr/ local/mysql/bin/mysql -uroot -P

//连接本地的。回车。输入公网ID。

Shell@Alicloud:~$ ssh root@47.112.159.55

再输入密码回车,再输入

[root@iZwz9bize6nk8hug8j0vywZ ~]# /usr/local/mysql/bin/mysql -uroot -P

回车。继续输入:查询原生的 MySQL 事务级别

mysql> show variables like ‘tx_isolation' :

图片2.png

看到隔离级别为 REPEATABLE-READ,可重复读。

两种隔离级别不一样。

2、事务的隔离级别

(1)MySQL InnoDB 存储引擎实现SQL标准的4种隔离级别,用来限定事务内外的哪些改变是可见的,哪些是不可见的;

(2)低级别的隔离级别一般支持更高的并发处理,并拥有更低的系统开销;

事务的隔离级别越低,对并发的支持越好。

 

二、MySQL 下事务的四种隔离级别

1、读未提交 (read uncommited)

在其中一个事务中,可以读取到其他事务未提交的数据变化。这种读取其他会话还未提交的事务,叫做脏读现象。在生产环境中不建议使用。

read uncommited 的隔离级别最低。

如,A客户端开启一个事务,这个事务没有执行 commited,也就是在提交之前,通过另外一个客户端能看到A客户端的数据。这种情况在实际数据库中不被允许。不管是哪种类型的数据库,一般不会采用 read uncommited 隔离级别。

2、读已提交 (read commited)

在其中一个事务中,可以读取到其他事务已经提交的数据变化。这种读取也可以叫做不可重复读,允许幻读现象的发生。

read commited 也是 Oracle 数据库默认的事务隔离级别

说明:A 客户端的事务已经 commited 后,另一个客户端才能读取到 A 客户端的数据。

若 A 客户端的事务发生了变更,另一个客户端在开启事务后,经过多次查询同一个数据表的数据,可能会出现不一致的情况。因为另一个客户端在查询过程中,A客户端的其他事务可能会发生数据提交。这样的情况就是幻读。

RDS for MySQL 默认事务级别也是 read commited。

3、可重复读 (repetable read)

它是 MySQL 默认的事务隔离级别,在其中一个事务中,直到事务结束前,都可以反复读取到该事务刚开始时看到的数据,并一直

不会发生变化,避免了脏读、不可重复读和幻读现象的发生

4、串行 (serializable)

在每个读的数据行 上都需要加表级共享锁,在每次写数据时都要加表级排它锁。这会造成 InnoDB 的并发能力下降,大量的超时和

锁竞争就会发生。

 

三、查看事务的隔离级别

1、MySQL 默认的事务隔离级别为可重复读 (repeatable read)。

2、RDS For MySQL 默认事务的隔离级别为读已提交 (read committed)

3、查询代码:show variables like tx_isolation';

(1)MySQL 默认的事务隔离级别

图片3.png

(2)RDS For MySQL 默认事务的隔离级别

图片4.png

 

四、演示实例

1、读未提交 (read uncommitted)

(1)开启两个 MySQL 连接客户端 session1 和 session2。

(2)分别将其当前 session 事务的隔离界别设置为 read uncomitted。

(3)session1 开启一个事务 ,并插入一条数据 。

(4)session2 执行查询,发现可以查询到 session1 刚插入的数据。

(5)实例。用 RDS 的 MySQL 演示

① 打开一个原生的 cloudshell 和一个 RDS 的 cloudshell。

先在 RDS 的 cloudshell 演示查询当前事务隔离级别

mysql> show variables 1ike ‘tx_isolation’;

图片5.png

看到隔离级别为 read committed。在原生的 cloudshell 中查询也是一样。

② 分别修改两个 cloudshell 事务的隔离级别

mysql>set session transaction isolation level read uncommitted; //代表修改当前 session 作用域的系统变量

Query OK,0 rows affected (0.00 sec)

mysql> show variables like ‘tx_isolation' ;

图片6.png

看到隔离级别变为 read uncommited。

③ 开启事务,插入数据

mysql> use aliyun;

Reading table information for completion of table and colunn names

You can turn off this feature to get a quicker startup with -A

Database changed

mysql> select * from user;  

图片7.png

//查询到 user 表有4条数据。然后分别开启两个 cloudshell 的事务。

mysql> begin;

Query OK,0 rows af fected (0.00 sec)

//在 RDS 的 cloudshell 里插入数据 5、sunqi

mysql> insert into user values (5,‘sunqi') ;

Query OK,1 row affected (0.00 sec)

mysql> select * from user;  

图片8.png

在原生的 cloudshell 里查询 user 表,也能查询到数据 5、sunqi。按照在 RDS 的cloudshell 里已经开启一个 begin,则在原生的 cloudshell 里是不能查询到新增数据的。因为原生的 cloudshell 里事务开启是未提交。但这时却能查询到,这就是读未提交 (read uncommited) 隔离级别的脏读现象。

2、读已提交 (read committed)

(1)开启两个 MySQL 连接客户端 session1 和 session2。

(2)分别将其当前 session 事务的隔离界别设置为 read committed

(3)session1 开启一个事务,并插入一条数据。

(4)session2 执行查询,发现不能查询到 session1 刚插入的数据,

直到 session1 事务提交。

(5)演示实例

① 分别回滚两个 cloudshell, 修改事务级别为读已提交

mysql> rol1back;

Query OK, 0 rows affected (0.00 sec)

mysql> set session transaction solation level read commnitted;

Query OK,0 rows affected (0.00 sec)

查询两个 cloudshell 的事务级别都变为 READ-COMMITTED。

② 分别 begin 两个 cloudshell 事务;

③ 然后在RDS的cloudshell里插入数据5、sunqi。

mysql> insert into user values (5,‘sunqi') ;

Query OK,1 row affected (0.00 sec)

mysql> select * from user;  

查询到新增数据 5 sunqi。

到原生的 cloudshell 里查询 user 表,发现只有4条数据,没有新增。不管查询多少次,都查询不到。因为 RDS 的 cloudshell 里的事务未提交,需要手动打开 commit 开启提交后到原生的 cloudshell 里才能查询到新增数据。这就是读已提交。

3、可重复读 (repeatable read)

(1) 开启两个 MySQL 连接客户端 session1 和 session2。

(2) 分别将其当前 session 事务的隔离界别设置为 repeatable read

(3) session1 开启一个事务,并插入-条数据。

(4) session2 在开启事务后,在整个事务提交或回滚前,始终无法查询到 session1提交的数据,即使是 session1 已经提交事务也依然查询不到。由此可见,可重复读就是确保在事务开启后的多次查询始终都是事务开启时的状态数据,直到当前事务提交或回滚。

在前边的示例中,RDS 的 cloudshell 里最开始 begin 事务时,只查询到4条数据。在原生的 cloudshell 里 begin 事务后查询也只能查到4条数据。当 RDS 的 cloudshell 里插入数据5,并且已经 commit 提交,再到原生的 cloudshell 里能查询到数据5。

这就是说。在一个事务开启之后,多次查询同一个表的数据可能会发生变化。这是读已提交。

可重复读是在事务开启后,其他事务也执行新的数据提交,即使执行多次查询,仍然只能看到事务开启时最开始的状态。

① 分别回滚两个 cloudshell, 修改事务级别为可重复读。

mysql> rol1back;

Query OK, 0 rows affected (0.00 sec)

mysql> set session transaction solation level repeatable read;

Query OK,0 rows affected (0.00 sec)

查询两个 cloudshell 的事务级别都变为 REPEATABLE READ。

② 分别 begin 两个 cloudshell 事务;

查询两个 cloudshell 都是4条数据。

③ 在 RDS 的 cloudshell 里插入数据 5 sunqi

RDS 的 cloudshell 里能查询到新增数据5。

在原生的 cloudshell 里查询不到新增数据5。

④ 在 RDS 的 cloudshell 里打开 commit 使事务持久化后,再去原生的cloudshell 里查询 user 表仍旧查询不到新增数据5。无论多少次都查询不到。直到原生的 cloudshell 里的事务 commit 提交或者回滚后,才能查询到新增数据。这就是可重复读。

4、串行化 (serializable)

(1) 开启两个 MySQL 连接客户端 session1 和 session2。

(2) 分别将其当前 session 事务的隔离界别设置为 serializable

(3) session1 开启一 个事务,并插入一条数据

(4) 当 session1 写数据且事务未提交前,session2 在开启事务后,执行 select 操作时会被阻塞,很明显出现了锁表。直到触发了锁表的超时时间。

(5) 演示示例

① 分别删除两个 cloudshell 的数据5

mysql> delete from user where id=5;

Query OK, 1 rows affected (0.00 sec)

查询两个 cloudshell 的数据都只有4条。

② 分别修改两个 cloudshell 的事务级别为 serializable ;

mysql> set session transaction isolation level serializable;

③ 分别 begin 两个 cloudshell 的事务

④ 在 RDS 的 cloudshell 里插入数据5 sunqi 后,在原生的 cloudshell 里查询 user 表就被阻塞了,在 RDS 的 cloudshell 里开启事务后,其他事务则不能进行查询了。在 RDS 的 cloudshell 里实际上是进行锁表的操作,直到进行提交或者回滚操作后,原生的 cloudshell 里查询的表才显示出来。如果 RDS 的 cloudshell 里再begin 一次,同样也会阻塞,因为之前的事务会结束。相当于是读已提交再加上一个串行化。

 

五、回顾

本章主要学习了:

1、事务的管理。包括什么是事务、事务的特性。事务的提交、回滚,和事务的ACID 特性。

2、MySQL 下怎么开启、提交、回滚事务这里用两个方式,一种是使用autocormit 手动设置;另一种是通过开启事务 begin 或 start transaction 命令方式。还有隐式提交事务、隐式回滚事务的比较和举例。

3、删除数据的两个命令 truncate 和 delete 的差异。truncate 不能回滚。delete 可以在事务下进行回滚。

4、四种隔离级别及其对比。

MySQL 默认隔离级别是 repetable read 可重复读。RDS for MySQL 是 read commited 读已提交。

隔离级别越低,效率越高,事务未提交就能读取,会出现脏读现象。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
131 6
|
30天前
|
存储 SQL 关系型数据库
MySQL的事务隔离级别
【10月更文挑战第17天】MySQL的事务隔离级别
97 43
|
1月前
|
SQL 关系型数据库 MySQL
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
MySQL中用于数据检索的`fetchone()`, `fetchmany()`, `fetchall()`函数的功能、SQL语句示例和应用场景。
57 3
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
|
1月前
|
SQL Ubuntu 关系型数据库
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
本文为MySQL学习笔记,介绍了数据库的基本概念,包括行、列、主键等,并解释了C/S和B/S架构以及SQL语言的分类。接着,指导如何在Windows和Ubuntu系统上安装MySQL,并提供了启动、停止和重启服务的命令。文章还涵盖了Navicat的使用,包括安装、登录和新建表格等步骤。最后,介绍了MySQL中的数据类型和字段约束,如主键、外键、非空和唯一等。
71 3
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
|
1月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1638 14
|
2月前
|
存储 Oracle 关系型数据库
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
从基本特性、技术选型、字段类型、事务提交方式、SQL语句、分页方法等方面对比Oracle和MySQL的区别。
531 18
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
|
1月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
1月前
|
存储 关系型数据库 MySQL
RR隔离级别在MySQL中的实现与幻读问题探讨
【10月更文挑战第3天】在数据库管理系统中,事务隔离级别是确保数据一致性和并发性能的关键要素。MySQL作为广泛使用的关系型数据库管理系统,支持多种事务隔离级别,其中可重复读(Repeatable Read,简称RR)是其默认隔离级别。本文将深入探讨RR隔离级别在MySQL中的实现原理,以及RR隔离级别下幻读问题的产生与解决方案。
75 2
|
1月前
|
关系型数据库 MySQL 数据库
Mysql学习笔记(四):Python与Mysql交互--实现增删改查
如何使用Python与MySQL数据库进行交互,实现增删改查等基本操作的教程。
64 1
|
2月前
|
SQL 关系型数据库 MySQL
MySQL基础:事务
本文详细介绍了数据库事务的概念及操作,包括事务的定义、开启、提交与回滚。事务作为一组不可分割的操作集合,确保了数据的一致性和完整性。文章还探讨了事务的四大特性(原子性、一致性、隔离性、持久性),并分析了并发事务可能引发的问题及其解决方案,如脏读、不可重复读和幻读。最后,详细讲解了不同事务隔离级别的特点和应用场景。
145 4
MySQL基础:事务