У меня есть PHP-скрипт, который использует PDO для подключения к базе данных SQLite. Допустим, база данных выглядит так (упрощенно):
ID A B
1 foo bar
2 abc xyz
3 def
Теперь предположим, что кто-то обращается к этому сценарию с помощью http://example.com/example.php?b=ghi. Затем сценарий должен найти первую (самую низкую ID
) строку с пустым значением в B
и вставить ghi
в B
,
Очевидно, я мог бы просто использовать что-то вроде этого (давайте представим, что я очистил переменную GET 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();
В моем случае это, вероятно, работало бы нормально в 99,9999% случаев. Но есть вероятность возникновения проблемы параллелизма, если два пользователя одновременно получают доступ к сценарию. Они могут получить тот же ряд (ID = 3
) от SELECT
заявление, и тогда кто-то догадывается, какое значение будет перезаписано другим.
Есть ли простой способ обойти это?