SQL 标准定义了四种隔离级别,MySQL 全都支持。这四种隔离级别分别是: 读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)、串行化(SERIALIZABLE) ,从左到右,隔离强度逐渐增强,性能逐渐变差,但是并发性变低
-
读未提交(READ UNCOMMITTED)
MySQL 事务隔离其实是依靠锁来实现的,加锁自然会带来性能的损失。而读未提交隔离级别是不加锁的,所以它的性能是最好的,没有加锁、解锁带来的性能开销。但有利就有弊,这基本上就相当于裸奔啊,所以它连脏读的问题都没办法解决。
-
读已提交(READ COMMITTED)
读已提交就是一个事务只能读到其他事务已经提交过的数据,也就是其他事务调用 commit 命令之后的数据。那脏数据问题就解决了。读已提交事务隔离级别是大多数流行数据库的默认事务隔离级别,比如 Oracle、SQL server、postgreSQL 等等,但是不是 MySQL 的默认隔离级别。
-
可重复读(REPEATABLE READ)
事务不会读到其他事务对已有数据的修改,即使其他事务已提交,也就是说,事务开始时读到的已有数据是什么,在事务提交前的任意时刻,这些数据的值都是一样的。但是,对于其他事务新插入的数据是可以读到的,这也就引发了幻读问题。
-
串行化(SERIALIZABLE)
串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 允许 | 允许 | 允许 |
读已提交 | 不允许 | 允许 | 允许 |
可重复读 | 不允许 | 不允许 | 允许 |
串行化 | 不允许 | 不允许 | 不允许 |
-
脏读
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。
与此同时,事务B正在读取张三的工资,读取到张三的工资为8000。
随后,事务A发生异常,而回滚了事务。张三的工资又回滚为5000。
最后,事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。 -
不可重复读
是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。
与此同时,事务B把张三的工资改为8000,并提交了事务。
随后,在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。 -
幻读
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
目前工资为5000的员工有10人,事务A读取所有工资为5000的人数为10人。
此时,事务B插入一条工资也为5000的记录。
这是,事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。
注意
- 不可重复读的重点是修改: 同样的条件,你读取过的数据,再次读取出来发现值不一样。
- 幻读的重点在于新增或者删除: 同样的条件,第 1 次和第 2 次读出来的记录数不一样。
-- 查看事务隔离级别
show variables like 'transaction_isolation';
-- 设置全局事务隔离级别
set global transaction isolation level read committed;
-- 设置当前会话事务隔离级别
set session transaction isolation level repeatable read;
Mysql默认的事务隔离级别是可重复读(Repeatable Read),那互联网项目中Mysql也是用默认隔离级别,不需要修改吗?
先说结论,互联网项目请用读已提交(Read Committed)这个隔离级别!
Read UnCommitted:一个事务读到另一个事务未提交读数据,肯定不合适。
Serializable:每个次读操作都会加锁,快照读失效,性能不佳。
- 原因一:在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多!
- 原因二:在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行。
https://www.jianshu.com/p/036f84d3f7c2
https://blog.csdn.net/song854601134/article/details/125147625