通过diffrenet键选择更新两次到同一个表导致MySQL

时间:2017-12-10 09:06:27

标签: mysql deadlock

  • 表格foo有id和name。
  • 交易A按ID 1选择更新。
  • 交易B按ID 1选择更新,然后等待。
  • 事务按名称选择更新任何内容(即使不存在)会导致事务B死锁。

为什么会这样?

下面的脚本会重现死锁。

create table foo (id int primary key, name varchar(100));
insert into foo values (1, 'foo1');

-- transaction A
start transaction;
select * from foo where id=1 for update;

-- transaction B
start transaction;
select * from foo where id=1 for update;
-- now waiting

-- transaction A
select * from foo where name='xxxxx' for update;
-- transaction B dead lock occer

1 个答案:

答案 0 :(得分:0)

我想出了接近的答案。

当没有索引列搜索的select更新时,MySQL会锁定所有记录。

https://dev.mysql.com/doc/refman/5.7/en/innodb-locks-set.html

  

如果没有适合您的语句的索引,并且MySQL必须扫描整个表来处理该语句,则表的每一行都会被锁定,这反过来会阻止其他用户对表的所有插入。

但是,我不知道为什么会导致死锁。

顺便说一句,我解决了我的问题,即每次选择更新以按主键搜索。