MySQL事务隔离级别

90 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

读未提交:read uncommitted(最低的隔离级别,没有提交就读到了)

什么是读未提交? ​ 事务A可以读取到事务B未提交的数据。 ​ 这种隔离级别存在的问题就是: ​ 脏读现象!(Dirty Read) ​ 我们称读到了脏数据。 ​ 这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是二档起步!

读已提交:read committed(提交之后才能读到)

什么是读已提交? ​ 事务A只能读取到事务B提交之后的数据。 ​ 这种隔离级别解决了什么问题? ​ 解决了脏读的现象。 ​ 这种隔离级别存在什么问题? ​ 不可重复读取数据。 ​ 什么是不可重复读取数据呢? ​ 在事务开启之后,第一次读到的数据是3条,当前事务还没有 ​ 结束,可能第二次再读取的时候,读到的数据是4条,3不等于4 ​ 称为不可重复读取。

这种隔离级别是比较真实的数据,每一次读到的数据是绝对的真实。 ​ oracle数据库默认的隔离级别是:read committed

可重复读:repeatable read(提交之后也读不到,永远读取的都是刚开启事务时的数据)

什么是可重复读取? ​ 事务A开启之后,不管是多久,每一次在事务A中读取到的数据 ​ 都是一致的。即使事务B将数据已经修改,并且提交了,事务A ​ 读取到的数据还是没有发生改变,这就是可重复读。 ​ 可重复读解决了什么问题? ​ 解决了不可重复读取数据。 ​ 可重复读存在的问题是什么? ​ 会出现幻影读。 ​ 每一次读取到的数据都是幻象。不够真实!

早晨9点开始开启了事务,只要事务不结束,到晚上9点,读到的数据还是那样! ​ 读到的是假象。不够绝对的真实。

mysql中默认的事务隔离级别就是这个!!

序列化/串行化:serializable(最高的隔离级别)

这是最高隔离级别,效率最低。解决了所有的问题。 ​ 这种隔离级别表示事务排队,不能并发! ​ synchronized,线程同步(事务同步) ​ 每一次读取到的数据都是最真实的,并且效率是最低的。

验证各种隔离级别

事务A 事务B

start transaction;
select * from t_user;
start transaction; 
insert into t_user values('zhangsan'); 
select * from t_user;

验证:

set global transaction isolation level read committed;

事务A 事务B

start transaction; 
start transaction; 
select * from t_user; 
insert into t_user values('zhangsan'); 
select * from t_user; 
commit; 
select * from t_user;

验证:

set global transaction isolation level repeatable read;

事务A 事务B

start transaction;
select * from t_user; 
insert into t_user values('lisi'); 
insert into t_user values('wangwu'); 
commit; 
select * from t_user;

验证:

set global transaction isolation level serializable;

事务A 事务B

start transaction;
select * from t_user;
insert into t_user values('abc'); 
select * from t_user;