一、事务隔离级别介绍
Mysql支持4中隔离级别,默认的是repeatable_read,可重复读。
隔离级别 | 描述 |
---|---|
read-uncommitted | 允许A事务读取其他事务未提交和已提交的数据。会出现脏读、不可重复读、幻读问题 |
read-committed | 只允许A事务读取其他事务已提交的数据。可以避免脏读,但仍然会出现不可重复读、幻读问题 |
repeatable-read | 确保事务可以多次从一个字段中读取相同的值。在这个事务持续期间,禁止其他事务对这个字段进行更新。可以避免脏读和不可重复读。但是幻读问题仍然存在。注意:mysql中使用了MVCC多版本控制技术,在这个级别也可以避免幻读。 |
serializable | 确保事务可以从一个表中读取相同的行,相同的记录。在这个事务持续期间,禁止其他事务对该表执行插入、更新、删除操作。所有并发问题都可以避免,但性能十分低下。 |
可以看到一大堆的概念,不用管,只需要知道 ==四个级别,三个问题。==
读未提交,读已提交,可重复读,串行化(读未,读已,重复,串)
脏读,不可重复读,幻读(想理解其中具体原理,看最下面)
隔离级别越高,问题越少,从三种到0种。
问题介绍:
- 脏读:事务A修改了数据,并未提交,事务B就看了这个被修改的数据。
- 不可重复读:事务A前后2次查询同一个表,结果不同。事务A自己并未修改这个表。这个表的数据是被事务B修改并提交了。
- 幻读:事务A前后2次查询同一个表,记录数不同。事务A自己并未添加和删除这个表的数据。事务B添加和删除了这个表的数据,并且提交了。
二、四种隔离级别的演示
接下来,通过mysql8来演示一下,这四种隔离级别。了解一下mysql的两个命令
set transaction_isolation='隔离级别'; // 设置隔离级别
select @@transaction_isolation;// 查看隔离级别
可以看到,mysql默认情况下是repeatable_read,可重复读。
1.read-uncommitted级别:
①演示脏读(read-uncommitted级别下):
第一步,设置两个客户端为读未提交:
第二步演示:
本来应该是左边提交了事务(commit;),右边才能读到“脏读快递”的,所以这就是幻读。
2.read-committed级别:
①避免脏读(read-committed级别下):
这个级别下继续按照刚刚的操作步骤,并没有发生脏读,所以read-committed避免了脏读。
②演示不可重复读(read-committed级别下):
“事务右”前后读取不一致,正式因为“事务左”修改并提交了,这样的话“事务右”就不知道是自己改了还是“事务左”给改的。
③演示幻读(read-committed级别下):
因为mysql的read-committed避免了幻读,所以我们就在读已提交的级别下演示:
3.read-committed级别:
本来此级别下是有幻读问题的,但mysql在此级别下用mvcc机制解决了该问题。想知道mvcc是什么的,之后的文章再讲解。
解决了脏读,不可重复读。
解决了幻读
4.serializable级别:
repeatable-read 与 serializable的区别:
repeatable-read:行锁机制。事务A和事务B,可以操作同一个表,但是不能操作同一行的数据。(行锁需要依赖于主键和唯一键)效率高
serializable:表锁机制。事务A和事务B,不可以操作同一个表。效率低,安全级别最高。