DDL(mysql8.0,5.7差不多)
create table testbigdata.test_dead_lock
(
id int auto_increment
primary key,
classid int null,
deleted tinyint null,
constraint idx_classid
unique (classid)
);
T1
start transaction with consistent snapshot ; //立即开启事务
select sleep(5);
select * from test_dead_lock where classid > 234 ; //因为是快照读,所以不会出现幻读
select sleep(10);
select * from test_dead_lock where classid > 234 for update ; //因为for update/(lock in share mode)所以该select变成了当前读,所以会出现幻读,(如果这句不加for update 或 for share,那么这句在当前事务内使用同一个视图,所以不会出现幻读)
commit ;
T2
begin;
insert into test_dead_lock (classid, deleted) VALUES (600,0);
commit;
所以,RR级别下只解决了普通select下的幻读(快照读),如果是当前读(加了 for update / lock in share mode)则还是会出现幻读。
为什么第一个句不加 for update等,因为update操作都会加排他锁,此时无论此处的select 加S锁还是X锁,都是互斥了的,只会等待该事务commit了,释放锁了,T2才会执行。