加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

由并发INSERT和SELECT引起的MySQL死锁

发布时间:2020-12-12 16:35:27 所属栏目:MsSql教程 来源:网络整理
导读:MySQL版本:5.6 存储引擎:InnoDB 当两个任务尝试选择然后插入同一个表时发生死锁.程序如下: Task_1 Task_2 ------ ------Phase 1 | SELECT SELECTPhase 2 | INSERT INSERTSELECT count(id) from mytbl where name = 'someValue' and timestampdiff(hour,ts
> MySQL版本:5.6
>存储引擎:InnoDB

当两个任务尝试选择然后插入同一个表时发生死锁.程序如下:

Task_1       Task_2
          ------      ------
Phase 1 | SELECT      SELECT
Phase 2 | INSERT      INSERT

SELECT count(id) from mytbl where name = 'someValue' and timestampdiff(hour,ts,now()) < 1;
INSERT mytbl (id,name,ts) values ('newId','anotherValue',now());

死锁日志如下(一些细节被截断):

------------------------
LATEST DETECTED DEADLOCK
------------------------
151225  8:22:17
*** (1) TRANSACTION:
TRANSACTION 0 746402,ACTIVE 0 sec,process no 4690,OS thread id 140411390486272 inserting
mysql tables in use 1,locked 1
LOCK WAIT 1172 lock struct(s),heap size 112624,32914 row lock(s)
MySQL thread id 3909,query id 31751474 10.20.36.38 mydb update
INSERT INTO mytbl -- truncated
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 5044 n bits 88 index `PRIMARY` of table `MYDB`.`mytbl` trx id 0 746402 lock_mode X insert intention waiting
Record lock,heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) TRANSACTION:
TRANSACTION 0 746449,OS thread id 140411389953792 inserting,thread declared inside InnoDB 500
mysql tables in use 1,locked 1
1172 lock struct(s),32914 row lock(s)
MySQL thread id 3906,query id 31751477 10.20.36.38 mydb update
INSERT INTO mytbl  -- truncated
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 5044 n bits 88 index `PRIMARY` of table `MYDB`.`MYTBL` trx id 0 746449 lock mode S
Record lock,heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 5044 n bits 88 index `PRIMARY` of table `MYDB`.`MYTBL` trx id 0 746449 lock_mode X insert intention waiting
Record lock,heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** WE ROLL BACK TRANSACTION (2)

问题

>根据MySQL手册,简单的SELECT语句使用不需要S锁定的快照读取. INSERT语句需要插入单行上的X锁.那么为什么Task_2持有S锁并导致僵局?

编辑

SHOW CREATE TABLE的结果如下:

| task_content | CREATE TABLE `mytbl` (
`id` bigint(20) NOT NULL,`ts` timestamp NULL DEFAULT NULL,`name` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

解决方法

如果您当前的隔离级别可重复读取或更强,则为了能够在事务中重复相同的结果(select count(id))… MySQL必须锁定整个主键(或者WHERE条件使用的另一个键的一部分) ).然后通过插入一个新值修改该键.但是并发事务会修改密钥的状态,这已经被看到了.两者都可以以相同的密钥状态开始,然后等待另一个完成,没有任何更改,这样它将应用自己的更改.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读