日常问题记录:更新数据库锁表(Lock wait timeout exceeded)

问题:并发更新sql出现锁表的情况


image.png

解决:添加索引
分析:我这里是两个字段,考虑添加联合索引或者唯一索引
测试:
1、联合索引情况

//创建联合索引
CREATE INDEX idx_command ON ids_rule(sid,type);
//选两条测试数据,确保数据存在
select count(1) from ids_rule where sid="2033907" and type =4;
select count(1) from ids_rule where  sid="2101402" and type =4;
//开启事务,运行其中一条更新数据,但是不提交
begin;
update ids_rule set action="t823safas2w3k" where sid="2033907" and type =4;

//测试更新同一条数据
update ids_rule set action="t823w3k" where sid="2033907" and type =4;
//测试更新其他数据
update ids_rule set action="2weqewrsdadfw32" where sid="2101402" and type =4;
更新其他数据.png
更新同一条数据.png

2、唯一索引情况

DROP INDEX idx_command  ON ids_rule;

ALTER TABLE `ids_rule` ADD UNIQUE INDEX `unix_sid`(`sid`);
更新同一条数据.png

更新其他数据.png

测试结论:添加索引后锁行,不添加索引锁表。

注意:有同事反馈更新不存在的数据会出现局部锁,局部锁指的是更新这条数据id附近的数据会被锁住,但我测试没有复现,鉴于谨慎考虑,如果你的业务场景是不存在则插入,存在则更新,那么使用联合索引/唯一索引都可以,如果只是一个更新操作,存在更新数据库中没有的数据的情况,建议建立唯一索引。

你可能感兴趣的:(日常问题记录:更新数据库锁表(Lock wait timeout exceeded))