[英]Avoid dead lock by ordering explicitly
我想明确提供一个关于MySql InnoDB如何获取行锁的命令。 如果可能的话,不应该有任何死锁只是停滞。 (如果我们遵循惯例。)
首先,数据库应按升序锁定表“模型”中的所有行。 然后第二个表“颜色”中的所有行应按升序锁定。 有没有办法控制数据库首先锁定表“模型”然后“颜色”?
举个例子:
start transaction;
select *
from models m
join colors c on c.model_id = m.id
where c.id IN (101, 105, 106)
order by m.id asc, c.id asc
for update;
虽然您可以通过straight_join执行此操作,但您还可以通过复制select ...来更新您想要获取的行来显式获取所需行的锁定。
CREATE TEMPORARY TABLE colorsToUpdate (
colorID BIGINT(20) NOT NULL,
modelID BIGINT(20) NOT NULL
);
insert into colorsToUpdate ( colorID, modelID)
SELECT id, model_id
FROM colors
where id in (101, 105, 106);
#This will try to acquire lock on models
select m.* from models m
join colorsToUpdate c
on c.modelID = m.id
for UPDATE;
#this will try to get locks on models, and colors.
select m.*, c.*
from colorsToUpdate u
left join models m
on u.modelID = m.id
join colors c
on u.colorID = c.ID
order by m.id asc, c.id asc
for update;
# do your data modification here.
drop table colorsToUpdate;
由于锁定是在多个步骤中完成的,因此可以在设置临时表和完成两个表上的锁定之间修改表“颜色”中的条目。
这对你来说可能没问题(例如,如果你只想修改现有的条目,当交易开始时),但如果它不是你想要的,可能会导致细微的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.