MySQL间隙锁、行锁的读写阻塞实验
结论
普通查询 | 查询(加共享锁) | 查询(加排它锁) | 插入/更新 | |
---|---|---|---|---|
间隙锁 | 不阻塞 | 不阻塞 | 不阻塞 | 阻塞 |
行锁 | 不阻塞 | 阻塞 | 阻塞 | 阻塞 |
MySQL版本:5.7.26
实验过程
- 写一个程序模拟实际代码:
@SneakyThrows
@Transactional
public String testPessimisticWrite(String username) {
log.info("start query");
// select * where testtable0_.username=:username for update;
TestTable testTable1 = testTableDao.findPessimisticWriteByUsername(username).orElse(null);
log.info("finished query" + testTable1);
// (1)
TimeUnit.SECONDS.sleep(6000);
return "ok";
}
- TestTable表结构及数据:
- 启用一个线程调用
1.
中方法查询username:233
- 启用一个线程调用
1.
中方法查询username:2334
以上两个线程都会在(1)
处阻塞。
此时用数据库管理工具去查询一下这两条数据:
-
使用普通查询语句:
select * from test_table where username = <username>
- 查询
233
不会阻塞 - 查询
2334
不会阻塞
- 查询
-
使用
lock in share mode
查询语句:select * from test_table where username = <username> lock in share mode
- 查询
233
会阻塞 - 查询
2334
不会阻塞
- 查询
-
使用
for update
查询语句:select * from test_table where username = <username> for update
- 查询
233
会阻塞 - 查询
2334
不会阻塞
- 查询
-
插入
2334
:会阻塞