事务隔离级别
read uncommitted(未提交读),导致脏读。
read committed(提交读),导致不可重复读。
repeatable read(可重复读),导致幻读。
serializable(序列化), 效率过低。
我们的隔离级别都是针对多个事务操作同一数据来定义的,比如未提交读,那就是当前事务隔离级别设置为未提交读,那么其他事务中未commit的数据当前事务可以读取。
默认的事务隔离级别是 repeatable read
mysql> show variables like '%isolation%' ;
+-----------------------+-----------------+
| Variable_name | Value |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
| tx_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
表结构
create table
create table student(
id int primary key,
name varchar(255)
);
insert into student values(1,'student1');
select * from student;
read uncommitted(未提交读)
客户端A
set session transaction isolation level read uncommitted;
start transaction;
select * from student;
客户端B
set session transaction isolation level read uncommitted;
set session transaction isolation level read committed;
set session transaction isolation level repeatable read;
set session transaction isolation level serializable;
start transaction;
update student set name ='student2' where id = 1;
select * from student ;
rollback;
只要客户端A的隔离级别为 read uncommitted,客户端B的隔离级别为任意级别,客户端A都会脏读。
serializable(序列化)
事务B阻塞
客户端A 先执行
set session transaction isolation level serializable;
start transaction;
select * from student;
客户端B 后执行
update student set name ='student2' where id = 1; --将会阻塞
客户端A阻塞
客户端B 先执行
start transaction;
update student set name ='student2' where id = 1;
客户端A 后执行
set session transaction isolation level serializable;
start transaction;
select * from student; --将会阻塞
总结
客户端 | A | B | 事务A sql执行结果 |
---|---|---|---|
隔离级别 | read uncommitted | 任意 | A读取出B事务中未提交的数据 |
隔离级别 | read committed | 任意 | A没有读出B事务中未提交的数据 |
隔离级别 | repeatable read | 任意 | A没有读出B事务中未提交的数据,并且在A开启事务后查询,无论B事务是否提交,读取的结果都是一致的。 |
隔离级别 | serializable | 任意 | A没有读取B事务中未提交的数据,并且在A开启事务查询后, B事务的更新相关数据会阻塞。B事务开启事务后并更新数据,A读取相关数据会阻塞。 |
read uncommitted ,read uncommitted,repeatable read 都是读取数据,其他事务的隔离级别对其读取不会造成阻塞。
serializable 可能由于其他事务更新数据,导致当前读取,更新相关数据 阻塞。