我遇到了一个僵局问题,而我却没有明确的解决方案。我在每次执行时都以相同的方式对查询进行排序,我认为这会阻止其他进程也将其锁定。请记住,此查询每秒可以被打数十次。

死锁查询如下:

BEGIN TRANSACTION
update `user_events`
    set `latest` = 0
    where (`resource_id` = 105
      and `latest` = 1
      and `member_id` = 52632)
      and `eventtype` in ('user_watched', 'user_unwatched');
COMMIT


表PK:id(查询中不需要)
索引:resource_idmember_idlatest

在此查询之后,我们然后插入最新行,最新行设置为1。因此,上一个查询的工作是为任何给定事件设置latest = 0,因此我们只关心所显示的两个事件中的最新事件。

任何帮助是极大的赞赏。

最佳答案

您需要一个复合索引:

INDEX(resource_id, latest, member_id, eventtype)


(列的顺序可能并不重要。)

如果没有这样的索引,则查找该行的速度会变慢,并且锁定的行将超出必要的数量。

拥有索引将消除大多数僵局。但是您仍然应该检查是否有错误,如果发现任何错误,请重播事务。

关于mysql - 处理UPDATE中的死锁,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57104872/

10-12 04:33