MySQL事务的隔离级别

专栏持续更新中:MySQL详解

一、隔离级别概念

事务的隔离级别就是对事务并发的控制

MySQL支持的四种隔离级别是:

  1. TRANSACTION_READ_UNCOMMITTED:未提交读。说明在提交前事务A可以看到事务B的变化。这样脏读,不可重复读和幻读都是可能发生的。
  2. TRANSACTION_READ_COMMITTED:已提交读(oracle默认),说明读取未提交的数据是不允许的(防止脏读)。在这个级别不可重复读和幻读可能发生的。
  3. TRANSACTION_REPEATABLE_READ:可重复读(MySQL默认),说明事务保证能够再次读取相同的数据而不会失败,即使其他的事务把这个数据改了,你也不会看到前后两次查询的数据的不同,完全可以保证两次查询的结果是一样的,但是幻读仍然会出现。
  4. TRANSACTION_SERIALIZABLE:串行化,是最高的事务隔离级别,它防止脏读,不可重复读和幻读。串行执行,相当于是单线程操作,并发能力最低
  • 事务隔离级别越高,为避免冲突所花费的性能也就越多
  • 在可重复读级别,实际上可以解决部分的幻读问题,但是不能防止update更新产生的幻读问题,要禁止幻读产生,还是需要设置串行化隔离级别

两个MySQL客户端默认工作在可重复读级别

二、测试READ-UNCOMMITTED隔离级别

先设置为最低的隔离级别:未提交读

若此时A客户端rollback了,数据库中zhangsan的年龄恢复成了20,那这时候已经来不及了,B客户端拿着年龄21去做业务了

两个客户端都rollback,放弃当前事务对数据做出的改变,zhangsan的年龄恢复为20

三、测试TRANSACTION_READ_COMMITTED隔离级别

由于设置了已提交读隔离级别,事务B并没有发生脏读,这是由各种锁机制以及事务并发的MVCC版本控制实现的

查询到了已经commit的数据,发生了不可重复读,这在已提交读隔离级别是允许发生的

既然发生了不可重复读,幻读就肯定可以发生了

四、测试TRANSACTION_REPEATABLE_READ隔离级别

提交刚才事务,设置可重复读隔离级别

可重复读隔离级别:对于一个事务来说,可以放心读数据,就算有其他事务修改了数据并且已经提交了,也不会在当前事务表现出来。只要自己没改,数据都是不会变的

在可重复读隔离级别,测试幻读(在一定程度上防止了幻读,但没有完全防止)

可以看到,在当前的可重复读隔离级别,右侧事务无法查询到左侧事务insert的数据,虽然看不到,但由于左侧事务已经提交,数据库表中是存在name为aaa的数据的,由于MVCC控制,右侧事务无法看见。但可以直接操作这条看不见的数据,操作以后,数据可以出现

右边的客户端update左侧客户端insert的数据:

实际上,事务A已经插入并且提交了,aaa已经存在,因为事务B update aaa的年龄成功了

前后两次同样的查询,后一次查询与前一次查询的数据量不同,就发生了幻读。也就是可重复读隔离级别下,并没有解决幻读的问题,要彻底解决幻读,就需要设置串行化隔离级别

五、测试TRANSACTION_SERIALIZABLE隔离级别

由于事务B正在读数据,此时事务A再写数据就被阻塞了(用读写锁实现,允许读读,不允许读写或者写写)

MySQL server不会让自己执行事务的线程永远阻塞,导致当前线程占用的锁无法释放,而使得其他执行事务的线程也无法获得锁而永远阻塞。所以当线程等待时间过长时,会让超时线程释放锁,并会返回一个错误:

相关推荐
20242817李臻25 分钟前
20242817李臻-安全文件传输系统-项目验收
数据库·安全
江城开朗的豌豆27 分钟前
JavaScript篇:对象派 vs 过程派:编程江湖的两种武功心法
前端·javascript·面试
行思理37 分钟前
MongoDB慢查询临时开启方法讲解
数据库·mongodb
bbsh20991 小时前
WebFuture 升级提示“不能同时包含聚集KEY和大字段””的处理办法
数据库·sql·mysql·webfuture
江城开朗的豌豆1 小时前
JavaScript篇:字母侦探:如何快速统计字符串里谁才是'主角'?
前端·javascript·面试
江梦寻1 小时前
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
开发语言·后端·python·macos·架构·策略模式
风象南1 小时前
SpringBoot的4种死信队列处理方式
java·spring boot·后端
互联网全栈架构2 小时前
遨游Spring AI:第一盘菜Hello World
java·人工智能·后端·spring
Zfox_5 小时前
Redis:Hash数据类型
服务器·数据库·redis·缓存·微服务·哈希算法
陈丹阳(滁州学院)7 小时前
若依添加添加监听容器配置(删除键,键过期)
数据库·oracle