我在中高负载情况下遇到了死锁。这是详细信息。
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,
表:订单项
# 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 未定义为外键,但在应用程序中用作外键
- Order 与 OrderItem 具有一对多关系
- OrderItem.order_id + OrderItem.f1 + OrderItem.f2 是唯一的
用例:
- 每当需要更新 Order 或 OrderItem 中的任何记录时,我想使旧记录失效(或删除)并插入新记录。
- 可能发生的情况是,早些时候,Order 中的一条记录(例如 order1)在 OrderItem 中有 3 条记录(例如 orderItem1、orderItem2、orderItem3)。但现在我想将其设置为 order1->orderItem1、orderItem4、orderItem5 或全新的集合。这就是为什么我想使所有旧记录一起失效并插入新记录的原因,因为找出 OrderItem 中更改的内容很复杂。
多个线程会做这个操作;但他们将在不同的记录集上工作。我一次处理 25 个Order
我尝试了什么:
- 插入订单;在重复键更新 Order 并从 OrderItem 中删除所有子项并插入 OrderItem s。
- 在 Order 中有另一个名为 is_active 的列,并将相同 sno 的所有记录标记为 0,并将新记录插入 >订单;将新的 child 插入到 OrderItem。
- 从给定 sno 的 Order 中删除;从 OrderItem 中删除相同的 sno。重新插入到两个表中。
上述所有方法有时都会导致死锁。 没有其他线程或进程正在处理这些表。
观察:
通过以下链接
并发现更新/删除多条记录会导致 MySQL 在 REPEATABLE_READ 隔离级别(默认)获得 Next Key 锁。在我看来,这会导致问题。
如果您能提供一些解决此问题的指导,我们将不胜感激。
最佳答案
既然你没有提到它,我试试看,你试过“FOR UPDATE”了吗?
将连接自动提交设置为 false。
在程序开始时,使用它来锁定所有相关数据。
SELECT o.* , oi.*
FROM order o
INNER JOIN orderitem oi ON (o.id=oi.order_id)
WHERE o.id = <order id to update>
FOR UPDATE;
然后你可以对这些条目做任何你想做的事情。 然后提交。
编辑:我认为问题的根本原因是多线程(很明显),我在想从等式中删除该元素是否更好。
想象一个系统,您有多个接收请求的接收器。这些接收器只会做类似的事情:
//select to check if there is a existing record(no need to lock), if no, return fail as response
SELECT o.* , oi.*
FROM order o
INNER JOIN orderitem oi ON (o.id=oi.order_id)
WHERE o.sno = <sno to update>;
insert into request_buffer (request_id, sno, new_order_item,create_date .......)
values
(1, abc , orderitem1......);
//return success after inserting buffer.
您有一个单独的单线程程序来汇集此表并处理这些缓冲区条目。
在那种情况下,它将多线程元素与数据库更新过程分开。我不确定传入请求的数量,但我认为如果您在每个周期/查询中处理更多请求,那么性能不会有太大不同吗?
关于插入和更新时的Mysql死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24819851/