我想在MySQL 5.7上显式生成间隙锁定死锁,以确保我的应用程序正确处理间隙锁定导致的死锁。我试图在网上遵循各种简单的例子,但是我不能解决僵局。我想生成MySQL检测到死锁并回滚其中一个事务(让另一个事务通过)的情况。
我测试这个的方式是我打开两个MySQL命令行窗口,在两个窗口中我都start transaction;
,然后双方各自的查询尝试模拟它。
我尝试的几个例子是: http://thushw.blogspot.com.mt/2010/11/mysql-deadlocks-with-concurrent-inserts.html
并且:https://www.percona.com/blog/2012/03/27/innodbs-gap-locks/
5.7中的某些内容发生了变化,这使得它可以更好地检测间隙锁并避免它们。是否还有其他可以生成的简单示例?
答案 0 :(得分:0)
这个问题可能已经过时。但是,我仍然想发布我的答案,以帮助其他有相同问题的人。
- 使用docker初始化Mysql 5.7环境:
docker compose 文件如下:
version: '3.3'
services:
mysql:
image: mysql:5.7
container_name: lzy-test-db-mysql-57
environment:
MYSQL_ROOT_PASSWORD: xxxxx
MYSQL_DATABASE: xxxxx
MYSQL_USER: xxxxx
MYSQL_PASSWORD: xxxxx
ports:
- 3307:3306
启动您的 mysql 5.7 docker :
PS E:\docker-env\test\mysql\57> ls
Directory: E:\docker-env\test\mysql\57
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/23/2020 10:26 AM 539 docker-compose.yml
PS E:\docker-env\test\mysql\57> docker-compose up -d
Creating network "57_default" with the default driver
Creating lzy-test-db-mysql-57 ... done
- 连接到您的mysql服务器。检查环境。 tx_isolation应该为RR
mysql> show variables like '%isolation%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
- 创建表格
CREATE TABLE `t` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
KEY `p_name` (`name`)
) ENGINE=InnoDB CHARSET=utf8;
- 准备数据
insert into t (name) value ('A'), ('C'), ('D');
- 生成间隙锁死锁
+====================================+============================================================+
| Session A | Session B |
+====================================+============================================================+
| begin; | |
+------------------------------------+------------------------------------------------------------+
| | begin; |
+------------------------------------+------------------------------------------------------------+
| delete from t where name = 'C'; | |
+------------------------------------+------------------------------------------------------------+
| | delete from t where name = 'C'; --Blocked! |
+------------------------------------+------------------------------------------------------------+
| insert into t (name) values ('B'); | |
+------------------------------------+------------------------------------------------------------+
| | ERROR 1213 (40001): Deadlock found when trying to get lock |
+------------------------------------+------------------------------------------------------------+
此死锁发生的原因,请参阅https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onbeforeunload