我有很多执行不同任务的控制台应用程序。我从php脚本获得了独特的任务:
$mysqli->autocommit(FALSE);
$result = $mysqli->query("SELECT id, task FROM queue WHERE locked = 0 LIMIT 1 FOR UPDATE;");
while($row = $result->fetch_assoc()){
$mysqli->query('UPDATE queue SET locked = 1 WHERE id="'.$row['id'].'";');
$mysqli->commit();
$response["response"]["task"] = $row["task"];
}
$mysqli->close();
echo json_encode($response);
有时我有重复的任务,"在尝试锁定时发现死锁;尝试重新启动事务"。 我做错了什么?
UPD:设置索引"锁定"列解决问题
答案 0 :(得分:0)
来自MySQL文档How to Minimize and Handle Deadlocks:
为您的表添加精心挑选的索引。然后,您的查询需要扫描更少的索引记录,从而设置更少的锁。
向locked
列添加索引应解决此问题。如果没有它,SELECT
查询必须扫描表格,查找locked = 0
行,并且必须锁定它所经过的所有行。
如果向WHERE
子句中的列添加索引,它可以直接转到该记录并锁定它。没有其他记录被锁定,因此减少了死锁的可能性。