1. 程式人生 > >GAP鎖(間隙鎖,對唯一鍵,普通索引產生的不同影響)

GAP鎖(間隙鎖,對唯一鍵,普通索引產生的不同影響)

-- (1)先建表,用於證明普通索引,有無間隙鎖
-- 建立間隙表,name用的普通索引
drop table if exists  test_gap;
create table test_gap(
id int primary key auto_increment comment '主鍵',
name varchar(20) comment '名稱',
num int comment '數量',
beginTime dateTime comment '開始時間',
endTime dateTime comment '開始時間',
key idx_name(name)
) comment '測試間隙鎖表';


insert into test_gap(name,num,beginTime,endTime)
values('a',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day) ),
('b',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day)),
('c',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day)),
('d',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day)),
('e',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day));




-- (2)模擬間隙鎖,普通索引,有間隙鎖
-- 打印出RR
show variables like '%isolation%';


-- transation 1 命令視窗1


set autocommit = 0;


update test_gap set num = num-1 where num-1>0 and now() between beginTime and endTime  and name = 'e';


-- commit 在視窗1,先別急著提交,等執行transtion 2 的插入語句後,再提交
commit;


-- transtion 2 命令視窗2


set autocommit = 0;


-- 這裡的insert會阻塞,需要先去transtion 1手動commit之後,insert才會插入成功
insert into test_gap(name,num,beginTime,endTime)
values('e1',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day) );


commit;








-- (3)建表,用於證明唯一索引,查詢條件豐富,也無間隙鎖
-- 建立間隙表,注意name用的唯一索引
drop table if exists  test_gap2;
create table test_gap2(
id int primary key auto_increment comment '主鍵',
name varchar(20) comment '名稱',
num int comment '數量',
beginTime dateTime comment '開始時間',
endTime dateTime comment '開始時間',
unique key uk_name(name)
) comment '測試間隙鎖表2';


insert into test_gap2(name,num,beginTime,endTime)
values('a',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day) ),
('b',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day)),
('c',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day)),
('d',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day)),
('e',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day));


-- 唯一索引,無間隙鎖
-- transation 1 命令視窗1


set autocommit = 0;


update test_gap2 set num = num-1 where num-1>0 and now() between beginTime and endTime  and name = 'e';


-- commit 在視窗1,先別急著提交,等執行transtion 2 的插入語句後,再提交
commit;


-- transtion 2 命令視窗2


set autocommit = 0;


-- 這裡的insert是不會阻塞的,儘管transtion 1的commit還沒執行
insert into test_gap2(name,num,beginTime,endTime)
values('e1',100,date_sub(now(),interval 1 day),date_sub(now(),interval -1 day) );


commit;