GAP鎖(間隙鎖,對唯一鍵,普通索引產生的不同影響)
阿新 • • 發佈:2019-02-09
-- (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;
-- 建立間隙表,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;