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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS AI 助手,专业版
简介: 快速学习 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 读已提交。

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

相关实践学习
自建数据库迁移到云数据库
本场景将引导您将网站的自建数据库平滑迁移至云数据库RDS。通过使用RDS,您可以获得稳定、可靠和安全的企业级数据库服务,可以更加专注于发展核心业务,无需过多担心数据库的管理和维护。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
9月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
7月前
|
SQL 关系型数据库 MySQL
MySQL锁机制:并发控制与事务隔离
本文深入解析了MySQL的锁机制与事务隔离级别,涵盖锁类型、兼容性、死锁处理及性能优化策略,助你掌握高并发场景下的数据库并发控制核心技巧。
|
8月前
|
存储 监控 Oracle
MySQL事务
MySQL事务具有ACID特性,包括原子性、一致性、隔离性和持久性。其默认隔离级别为可重复读,通过MVCC和间隙锁解决幻读问题,确保事务间数据的一致性和并发性。
MySQL事务
|
6月前
|
关系型数据库 MySQL 数据库
【赵渝强老师】MySQL的事务隔离级别
数据库并发访问时易引发数据不一致问题。如客户端读取到未提交的事务数据,可能导致“脏读”。MySQL通过四种事务隔离级别(读未提交、读已提交、可重复读、可序列化)控制并发行为,默认为“可重复读”,以平衡性能与数据一致性。
371 0
|
7月前
|
关系型数据库 MySQL 数据库
MySql事务以及事务的四大特性
事务是数据库操作的基本单元,具有ACID四大特性:原子性、一致性、隔离性、持久性。它确保数据的正确性与完整性。并发事务可能引发脏读、不可重复读、幻读等问题,数据库通过不同隔离级别(如读未提交、读已提交、可重复读、串行化)加以解决。MySQL默认使用可重复读级别。高隔离级别虽能更好处理并发问题,但会降低性能。
249 0
|
9月前
|
安全 关系型数据库 MySQL
mysql事务隔离级别
事务隔离级别用于解决脏读、不可重复读和幻读问题。不同级别在安全与性能间权衡,如SERIALIZABLE最安全但性能差,READ_UNCOMMITTED性能高但易导致数据不一致。了解各级别特性有助于合理选择以平衡并发性与数据一致性需求。
240 1
|
10月前
|
关系型数据库 MySQL 数据库
MySQL报错:未知系统变量'tx_isolation'及隔离级别查询
记住,选择合适的隔离级别,就像是在风平浪静的湖面上找到适合的划船速度——既要快到能赶上午饭(性能),又不至于翻船(数据一致性问题)。
390 3
|
存储 关系型数据库 MySQL
MySQL索引学习笔记
本文深入探讨了MySQL数据库中慢查询分析的关键概念和技术手段。
841 81
|
SQL 安全 关系型数据库
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
事务是MySQL中一组不可分割的操作集合,确保所有操作要么全部成功,要么全部失败。本文利用SQL演示并总结了事务操作、事务四大特性、并发事务问题、事务隔离级别。
5447 56
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
|
SQL 关系型数据库 MySQL
京东面试:MySQL MVCC是如何实现的?如何通过MVCC实现读已提交、可重复读隔离级别的?
1.请解释什么是MVCC,它在数据库中的作用是什么? 2.在MySQL中,MVCC是如何实现的?请简述其工作原理。 3.MVCC是如何解决读-写和写-写冲突的? 4.在并发环境中,当多个事务同时读取同一行数据时,MVCC是如何保证每个事务看到的数据版本是一致的? 5.MVCC如何帮助提高数据库的并发性能?
京东面试:MySQL MVCC是如何实现的?如何通过MVCC实现读已提交、可重复读隔离级别的?

推荐镜像

更多