导致死锁的MySQL查询
我正在处理一个导致死锁的查询,我相信这是因为它试图从正在更新的同一个表中进行选择。无论如何,这是一个非常笨拙的方法,我想找到一个更好的方法 这里一个显而易见的解决方案是将SELECT拖出到一个单独的查询中,但我希望在座的SQL忍者中有一位提出了一个更优雅的解决方案的建议,该解决方案可以在一个查询中以更少的开销完成这项工作导致死锁的MySQL查询,mysql,sql,sql-update,Mysql,Sql,Sql Update,我正在处理一个导致死锁的查询,我相信这是因为它试图从正在更新的同一个表中进行选择。无论如何,这是一个非常笨拙的方法,我想找到一个更好的方法 这里一个显而易见的解决方案是将SELECT拖出到一个单独的查询中,但我希望在座的SQL忍者中有一位提出了一个更优雅的解决方案的建议,该解决方案可以在一个查询中以更少的开销完成这项工作 SET @update_id := 0; UPDATE msgstream SET retryCount = retryCount + 1, retryT
SET @update_id := 0;
UPDATE msgstream
SET retryCount = retryCount + 1,
retryTime = TIMESTAMPADD(SECOND,?,NOW(3)),
messageid = (SELECT @update_id := messageid)
WHERE receiver = ?
AND isDelivered = 0
AND retryCount < 10
AND retryTime < NOW(3)
AND (
SELECT m.counter
FROM (
SELECT COUNT(messageid) AS counter
FROM msgstream
WHERE receiver = ?
AND isDelivered = 0
AND retryCount < 10
AND retryTime > NOW(3)
) AS m
) = 0
ORDER BY messageid LIMIT 1;
为什么需要子查询?死锁(如果您真正指的是死锁,并且不仅仅是查询花费了很长时间)是由至少两个需要相同资源的不同会话/事务引起的,但不幸的是,这导致它们相互阻塞。无论使用多少子查询,它都不能由单个查询引起。这肯定是死锁。它出现在日志中。如果它不是由一个查询引起的,无论它包含多少SELECT语句,那么它可能是这个查询被调用的次数中的某个东西,我也在处理这个问题。至于为什么我们需要子查询,很好的问题。。。我在这里能想到的最好的办法是,我们要确保没有其他消息发送给接收者,是retryTime>NOW3。问题是,这是应用程序中非常关键的一部分,所以我不想对其进行太大的更改,因为我无法100%确定为什么要这样做。