mysql - 存储过程中的 MySQL 解除阻塞
问题描述
我有下表 user_sessions:
CREATE TABLE `user_sessions` (
`session_key` varchar(36) NOT NULL,
`user_id` bigint(20) NOT NULL,
`is_active` tinyint(4) NOT NULL DEFAULT '1',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`guid` varchar(64) DEFAULT NULL,
PRIMARY KEY (`session_key`),
KEY `FK_user_sessions_user_logins` (`user_id`),
CONSTRAINT `FK_user_sessions_user_logins` FOREIGN KEY (`user_id`) REFERENCES `user_logins` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
然后我有 SP 正在做一些逻辑。SELECT
除了我正在user_sessions
使用以下查询进行更新的一个查询之外,此 SP 中的几乎所有语句都除外:
UPDATE user_sessions
SET updated_at = CURRENT_TIMESTAMP, guid = @guid
WHERE session_key = _token;
在此查询中,我收到此错误:Error Code: 1213. Deadlock found when trying to get lock; try restarting transaction
这是 MySQL v 5.7 的日志
*** (1) TRANSACTION:
TRANSACTION 85234691, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 108 lock struct(s), heap size 24784, 7702 row lock(s), undo log entries 1
MySQL thread id 176542, OS thread handle 46953148479232, query id 66288172 1.1.1.1 db updating
UPDATE user_sessions
SET updated_at = CURRENT_TIMESTAMP, guid = @guid
WHERE session_key = _token
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2614 page no 3 n bits 88 index PRIMARY of table `db`.`user_sessions` trx id 85234691 lock_mode X locks rec but not gap waiting
Record lock, heap no 21 PHYSICAL RECORD: n_fields 8; compact format; info bits 0
0: len 30; hex 61373366393238612d313137642d313165632d386638322d306135303537; asc a73f928a-117d-11ec-8f82-0a5057; (total 36 bytes);
1: len 6; hex 0000051493f0; asc ;;
2: len 7; hex bc000001ee0110; asc ;;
3: len 8; hex 800000000000000a; asc ;;
4: len 1; hex 81; asc ;;
5: len 5; hex 99aa92ed4b; asc K;;
6: len 5; hex 99aa92ed4b; asc K;;
7: len 30; hex 6b6f6c656b746f2d6170692d383164643233366638393865343932666234; asc db-api-81dd236f898e492fb4; (total 44 bytes);
*** (2) TRANSACTION:
TRANSACTION 85234689, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
108 lock struct(s), heap size 24784, 7702 row lock(s), undo log entries 1
MySQL thread id 176541, OS thread handle 46953147946752, query id 66288171 1.1.1.1 db updating
UPDATE user_sessions
SET updated_at = CURRENT_TIMESTAMP, guid = @guid
WHERE session_key = _token
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 2614 page no 3 n bits 88 index PRIMARY of table `db`.`user_sessions` trx id 85234689 lock mode S locks rec but not gap
Record lock, heap no 21 PHYSICAL RECORD: n_fields 8; compact format; info bits 0
0: len 30; hex 61373366393238612d313137642d313165632d386638322d306135303537; asc a73f928a-117d-11ec-8f82-0a5057; (total 36 bytes);
1: len 6; hex 0000051493f0; asc ;;
2: len 7; hex bc000001ee0110; asc ;;
3: len 8; hex 800000000000000a; asc ;;
4: len 1; hex 81; asc ;;
5: len 5; hex 99aa92ed4b; asc K;;
6: len 5; hex 99aa92ed4b; asc K;;
7: len 30; hex 6b6f6c656b746f2d6170692d383164643233366638393865343932666234; asc db-api-81dd236f898e492fb4; (total 44 bytes);
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2614 page no 3 n bits 88 index PRIMARY of table `kolekto`.`user_sessions` trx id 85234689 lock_mode X locks rec but not gap waiting
Record lock, heap no 21 PHYSICAL RECORD: n_fields 8; compact format; info bits 0
0: len 30; hex 61373366393238612d313137642d313165632d386638322d306135303537; asc a73f928a-117d-11ec-8f82-0a5057; (total 36 bytes);
1: len 6; hex 0000051493f0; asc ;;
2: len 7; hex bc000001ee0110; asc ;;
3: len 8; hex 800000000000000a; asc ;;
4: len 1; hex 81; asc ;;
5: len 5; hex 99aa92ed4b; asc K;;
6: len 5; hex 99aa92ed4b; asc K;;
7: len 30; hex 6b6f6c656b746f2d6170692d383164643233366638393865343932666234; asc kolekto-api-81dd236f898e492fb4; (total 44 bytes);
*** WE ROLL BACK TRANSACTION (2)
我尝试使用捕获死锁的包装函数并再尝试 2 次将 SP 作为准备好的语句调用,它几乎在所有情况下都有帮助,但是由于我添加了 user_sessions 表 - 它停止了。另外,尝试使用SELECT FOR UPDATE
但没有成功
解决方案
推荐阅读
- mysql-workbench - 输入关键字后如何自动大写MySQL?
- c# - 有没有办法使用类似于 .AsImplementedInterfaces() 的 JSON 配置在 Autofac 中为组件注册所有接口
- mysql - mysql - 如何仅更新从多个重复行中找到的第一行
- swiftui - 如何导出 .drawing 文件
- java - 如何在spring boot中保存对数据库的响应
- python - Jinja 不从应用程序导入表情数据
- javascript - 从 django settings.py 访问模板中脚本标签 src 的 API 密钥
- javascript - 打印由空格 js 分隔的所有字符
- python - 用于循环文件夹图像的烧瓶
- python - 如何将逗号放入整数输入中?