首页 > 数据库 >MySQL事务隔离级别详解

MySQL事务隔离级别详解

时间:2023-09-18 21:03:43浏览次数:46  
标签:事务 隔离 幻读 READ 详解 脏读 MySQL 级别

MySQL事务隔离级别详解 | JavaGuide(Java面试 + 学习指南)

事务隔离级别总结

SQL 标准定义了四个隔离级别:

  • READ-UNCOMMITTED(读取未提交) :最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
  • READ-COMMITTED(读取已提交) :允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
  • REPEATABLE-READ(可重复读) :对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • SERIALIZABLE(可串行化) :最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
隔离级别 脏读 不可重复读 幻读
READ-UNCOMMITTED
READ-COMMITTED ×
REPEATABLE-READ × ×
SERIALIZABLE × × ×

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过SELECT @@tx_isolation;命令来查看,MySQL 8.0 该命令改为SELECT @@transaction_isolation;

MySQL> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

从上面对 SQL 标准定义了四个隔离级别的介绍可以看出,标准的 SQL 隔离级别定义里,REPEATABLE-READ(可重复读)是不可以防止幻读的。

但是!InnoDB 实现的 REPEATABLE-READ 隔离级别其实是可以解决幻读问题发生的,主要有下面两种情况:

  • 快照读:由 MVCC 机制来保证不出现幻读。
  • 当前读:使用 Next-Key Lock 进行加锁来保证不出现幻读,Next-Key Lock 是行锁(Record Lock)和间隙锁(Gap Lock)的结合,行锁只能锁住已经存在的行,为了避免插入新行,需要依赖间隙锁。

因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是 READ-COMMITTED ,但是你要知道的是 InnoDB 存储引擎默认使用 REPEATABLE-READ 并不会有任何性能损失。

InnoDB 存储引擎在分布式事务的情况下一般会用到 SERIALIZABLE 隔离级别。

实际情况演示

在下面我会使用 2 个命令行 MySQL ,模拟多线程(多事务)对同一份数据的脏读问题。

MySQL 命令行的默认配置中事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。如果要显式地开启一个事务需要使用命令:START TRANSACTION

我们可以通过下面的命令来设置隔离级别。

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

我们再来看一下我们在下面实际操作中使用到的一些并发控制语句:

  • START TRANSACTION |BEGIN:显式地开启一个事务。
  • COMMIT:提交事务,使得对数据库做的所有修改成为永久性。
  • ROLLBACK:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。

脏读(读未提交)

img

避免脏读(读已提交)

img

不可重复读

还是刚才上面的读已提交的图,虽然避免了读未提交,但是却出现了,一个事务还没有结束,就发生了 不可重复读问题。

img

可重复读

img

幻读

演示幻读出现的情况

img

SQL 脚本 1 在第一次查询工资为 500 的记录时只有一条,SQL 脚本 2 插入了一条工资为 500 的记录,提交之后;SQL 脚本 1 在同一个事务中再次使用当前读查询发现出现了两条工资为 500 的记录这种就是幻读。

解决幻读的方法

解决幻读的方式有很多,但是它们的核心思想就是一个事务在操作某张表数据的时候,另外一个事务不允许新增或者删除这张表中的数据了。解决幻读的方式主要有以下几种:

  1. 将事务隔离级别调整为 SERIALIZABLE
  2. 在可重复读的事务级别下,给事务操作的这张表添加表锁。
  3. 在可重复读的事务级别下,给事务操作的这张表添加 Next-key Lock(Record Lock+Gap Lock)

标签:事务,隔离,幻读,READ,详解,脏读,MySQL,级别
From: https://blog.51cto.com/coderge/7515978

相关文章

  • Linux离线安装Mysql-5.7
    1、背景描述在真实业务场景下,Linux服务器一般位于内网,所以无法直接访问互联网资源;特别是安装数据库的Linux服务器,在网络方面的管控只会更加严格;因此,需要提前下载好相关资源,再传输到内网Linux服务器进行安装;2、下载Mysql的安装包下载地址:https://dev.mysql.com/downl......
  • 无法访问MySQL,错误代码1045 (28000): 用户'bill'@'localhost'被拒绝访问
    这个错误通常是由于权限设置不正确或者密码错误导致的。你可以尝试以下解决方案来解决这个问题:确保密码输入正确:在输入密码时要注意区分大小写,确保将正确的密码输入。检查用户权限:使用root用户登录MySQL,执行以下命令来查看用户bill的权限:SHOWGRANTSFOR'bill'@'localhost';确认用......
  • 视频汇聚/视频云存储/视频监控管理平台EasyCVR分发rtsp流起播慢优化步骤详解
    安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力,也具备接入AI智能分析的......
  • MySQL实战实战系列 04 深入浅出索引(上)
    提到数据库索引,我想你并不陌生,在日常工作中会经常接触到。比如某一个SQL查询比较慢,分析完原因之后,你可能就会说“给某个字段加个索引吧”之类的解决方案。但到底什么是索引,索引又是如何工作的呢?今天就让我们一起来聊聊这个话题吧。    数据库索引的内容比较多,我分成了......
  • mysql 复制表数据和uuid 生成
    复制表结构及数据到新表CREATETABLE新表SELECT*FROM旧表这种方法会将旧表中所有的内容都拷贝过来,当然我们可以用deletefrom新表;来删除。不过这种方法的一个最不好的地方就是新表中没有了旧表的primarykey、Extra(auto_increment)等属性。需要自己添加uuid生成selectrep......
  • 错误记录——mysql5.7连接失败,服务无法启动
    起因:上周安装完mysql后,成功新建了数据库,一切都是正常的,于是就先搁置一旁。今天周一过来,却突然发现无法连接mysql了。过程:第一反应是服务没有启动,毕竟重启了电脑,说不定是服务没有自动启动,于是打开了服务管理器,却发现没有mysql对应的服务。既然没有,那我就自己手动创建一......
  • 视频汇聚/视频云存储/视频监控管理平台EasyCVR分发rtsp流起播慢优化步骤详解
    安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力,也具备接入AI智能分析的......
  • Ubuntu安装MySQL Access denied for user ‘root‘@‘localhost‘
    1、其它用户登录MySQL2、#查看user表usemysql;selectuser,pluginfromuser;3、修改root密码格式#修改其密码格式updateusersetplugin='mysql_native_password'whereuser='root';#查询其用户selectuser,pluginfromuser;#刷新权限flushprivileges;4、增加root密码#......
  • KingbaseES V8R3集群运维案例之---主库数据库服务down后failover切换详解
    案例说明:对KingbaseESV8R3集群,主库数据库服务down后,failover切换进行分析,详解其执行切换的过程,本案例可用于对KingbaseESV8R3集群failover故障的分析参考。适用版本:KingbaseESV8R3集群架构:node_id|hostname|port|status|lb_weight|role|select_cnt......
  • 软件测试|MySQL CROSS JOIN:交叉连接的详细解析
    简介在MySQL数据库中,CROSSJOIN是一种用于生成两个或多个表的笛卡尔积的连接方法。CROSSJOIN不需要任何连接条件,它将左表的每一行与右表的每一行进行组合,从而生成一个包含所有可能组合的结果集。本文将详细介绍MySQL中的CROSSJOIN概念,并提供示例来加深理解。什么是CROSS......