从MySQL表中同时获取任务

时间:2017-01-04 15:42:49

标签: php mysql transactions deadlock

我有很多执行不同任务的控制台应用程序。我从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:设置索引"锁定"列解决问题

1 个答案:

答案 0 :(得分:0)

来自MySQL文档How to Minimize and Handle Deadlocks

  

为您的表添加精心挑选的索引。然后,您的查询需要扫描更少的索引记录,从而设置更少的锁。

locked列添加索引应解决此问题。如果没有它,SELECT查询必须扫描表格,查找locked = 0行,并且必须锁定它所经过的所有行。

如果向WHERE子句中的列添加索引,它可以直接转到该记录并锁定它。没有其他记录被锁定,因此减少了死锁的可能性。