测试工具
1. navicat
2. 利用多窗口模拟多线程
3. 建表初始化(用了之前文章的表,懒得改了)
测试用例
事务A | 事务B |
start transaction; | |
select * from gap_lock_test; | |
1 A 1 2 B 3 3 C 5 | |
start transaction; | |
insert into gap_lock_test values (4, 'Y', 100); | |
select * from gap_lock_test; | |
1 A 1 2 B 3 3 C 5 | |
insert into gap_lock_test values (4, 'Y', 100); | |
报错:duplicate key | |
update gap_lock_test set num = 123 where id = 4; | |
更新超时:事务B未提交,事务A抢不到id=4的行锁 | |
事务B提交
事务A | 事务B |
start transaction; | |
select * from gap_lock_test; | |
1 A 1 2 B 3 3 C 5 | |
start transaction; | |
insert into gap_lock_test values (4, 'Y', 100); | |
commint; | |
select * from gap_lock_test; | |
1 A 1 2 B 3 3 C 5 | |
insert into gap_lock_test values (4, 'Y', 100); | |
报错:duplicate key(当前读,读到了事务B提交数据) | |
update gap_lock_test set num = 123 where id = 4; | |
操作成功! | |
select * from gap_lock_test; | |
1 A 1 2 B 3 3 C 5 4 Y 100 update id = 4(当前读)这条数据后,再select(快照读)时产生了幻读 | |
commit; |
1. 第一步:事务A开启事务,执行查询操作,查询初始数据3条
2. 第二步:事务B插入 id = 4的数据后,事务B查询到4条数据
3. 事务A再执行查询语句,仍然是3条数据(为查询出事务B提交数据),满足RR
4. 事务A插入 id = 4数据报错(提示duplicate key)
5. 事务A更新 id = 4数据,执行成功;再查询时,发现查出了4条数据(产生了幻读,同一个事务A前后查询多出了一条数据,并且未执行 insert 操作)