我在中等到高负载情况下遇到死锁。这里是细节。Mysql在插入和更新时出现死锁
的MySQL-5.5.21-55
引擎:InnoDB的
表:订单
# Field, Type, Null, Key, Default, Extra
id, bigint(20) unsigned, NO, PRI, , auto_increment
sno, varchar(32), NO, MUL, ,
misc1, int, NO, , 0,
表:OrderItem的
# Field, Type, Null, Key, Default, Extra
id, bigint(20) unsigned, NO, PRI, , auto_increment
order_id, bigint(20), YES, MUL, ,
f1, varchar(50), YES, , ,
f2, varchar(100), YES, , ,
misc2, int, NO, , 0,
- 订购 .sno是唯一
- OrderItem的 .order_id没有被定义为外键,但用作应用外键
- 订购具有一个一对多关系与OrderItem的
- OrderItem的 .order_id + OrderItem的 .f1 + OrderItem的 .f2是唯一
USECASE:
- 每当订单或OrderItem的需要更新任何记录,我要废止旧记录(或删除),并插入新的。
- 可能因此发生较早,在订购一个记录(例如order1)有3条记录OrderItem的(例如orderItem1,orderItem2,orderItem3)。但现在我想把它作为order1-> orderItem1,orderItem4,orderItem5或全新的集合。这就是为什么我想要将旧记录全部无效并插入新记录以查明订单项变得复杂的原因。
多线程会做这个操作;但他们会在不同的记录集上工作。我在一个时间
我试了一下在25 订单经营:
- 插入订单;重复密钥更新订购并从订单项删除所有子项并插入订单项 s。
- 呼吁IS_ACTIVE在订单并标记为同一SNO的所有记录为0,并在秩序插入新记录的另一列;将新的子女插入订单项。
- 从删除订单给定的sno;从删除OrderItem为同一个sno.Insert插入两个表中新鲜。
以上所有方法都会导致无法锁定,有些时候或其他时间。 没有其他线程或进程正在处理这些表。
观察:
通过以下链接
去了,发现更新/删除多个记录导致MySQL获得下一个关键锁定一个t REPEATABLE_READ隔离级别(这是默认级别)。在我看来这导致了这个问题。
感谢您能否提供解决方案。
锁只锁定其他连接,不能在同一数据库连接上的操作之间发生死锁。 – Barmar
“新订单”动作如何触发...?一个简单的http请求? –
@Barmar连接不被线程共享。 –