I have a PHP script that uses PDO to connect to a SQLite database. Let's say the database looks like this (simplified):
ID A B
1 foo bar
2 abc xyz
3 def
Now, let's say that someone accesses this script using http://example.com/example.php?b=ghi. The script should then find the first (lowest ID
) row with an empty value in B
and insert ghi
into B
.
Obviously I could just use something like this (let's pretend I have sanitized the GET variable b
):
$row = $db->query("SELECT * FROM table WHERE B IS NULL OR B=''")->fetch();
$stmt = $db->prepare("UPDATE table SET B=:b WHERE ID=:id");
$stmt->bindValue(":b", $b);
$stmt->bindValue(":id", $row['ID']);
$stmt->execute();
In my case it would probably work fine in 99.99999% of all cases. But there is a chance of a concurrency problem if two users access the script at the same time. They could get the same row (ID = 3
) from the SELECT
statement, and then it's anyone's guess which value will be overwritten by the other one.
Is there an easy way to work around this?