MySQL и PDO: теоретически PDO::lastInsertId может дать сбой?
Я долго обдумывал это.
Рассмотрим веб-приложение огромных размеров, где, скажем, миллионы SQL-запросов выполняются каждую секунду.
Я запускаю свой код:
$q = $db->prepare('INSERT INTO Table
(First,Second,Third,Fourth)
VALUES (?,?,?,?)');
$q->execute(array($first,$second,$third,$fourth));
Затем сразу после этого я хочу получить автоматически увеличенный идентификатор этого последнего запроса:
$id = $db->lastInsertId();
Возможно ли, что lastInsertId потерпит неудачу, т.е. получит идентификатор некоторого SQL-запроса на вставку, который был выполнен между моими двумя блоками кода?
Secondary:
Если он может потерпеть неудачу, что будет лучшим способом устранить эту возможную утечку?
Было бы безопаснее создать еще один SQL-запрос для получения правильного идентификатора из базы данных, просто чтобы быть уверенным?
2 ответа
Это всегда будет безопасно при условии, что реализация PDO не делает что-то действительно головокружительное. Следующее из информации MySQL о last_insert_id
:
Сгенерированный идентификатор сохраняется на сервере для каждого соединения. Это означает, что значение, возвращаемое функцией данному клиенту, является первым значением AUTO_INCREMENT, сгенерированным для самого последнего оператора, влияющего на столбец AUTO_INCREMENT этим клиентом. На это значение не могут повлиять другие клиенты, даже если они генерируют собственные значения AUTO_INCREMENT. Такое поведение гарантирует, что каждый клиент может получить свой собственный идентификатор, не заботясь об активности других клиентов и не нуждаясь в блокировках или транзакциях.
LastInsertId для каждого соединения не требует запроса к серверу - mysql всегда отправляет его обратно в ответном пакете.
Так что, если метод execute не выдает исключение, тогда вы гарантированно получите правильное значение в lastInsertId.
Он никогда не даст вам идентификатор вставки чего-либо еще, если ваш запрос по какой-то причине не удался (например, неверный синтаксис), и в этом случае он может дать вам идентификатор вставки из предыдущего по тому же соединению. Но не кто-нибудь еще.