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-запроса, который был выполнен между моими двумя блоками кода?

Вторичный:

Если это может произойти с ошибкой, какой был бы лучший способ подключить эту возможную утечку?

Было бы безопаснее создать другой SQL-запрос для получения правильного идентификатора из базы данных, чтобы быть уверенным?

Ответ 1

Это всегда будет безопасно при условии, что реализация PDO не делает что-то действительно костяное. Ниже приведено описание MySQL на last_insert_id:

Идентификатор, который был сгенерирован, поддерживается на сервере для каждого подключения. Это означает, что значение, возвращаемое функцией для данного клиента, является первым значением AUTO_INCREMENT, сгенерированным для самого последнего оператора, влияющим на столбец AUTO_INCREMENT этого клиента. Это значение не может повлиять на других клиентов, даже если они генерируют собственные значения AUTO_INCREMENT. Такое поведение гарантирует, что каждый клиент может получить свой собственный идентификатор, не заботясь о деятельности других клиентов, и без необходимости блокировок или транзакций.

Ответ 2

Нет. lastInsertId - для каждого соединения и не требует запроса на сервер - mysql всегда отправляет его обратно в свой пакет ответов.

Итак, если метод execute не генерирует исключение, то вы гарантированно получите правильное значение в lastInsertId.

Он никогда не даст вам идентификатор вставки чего-либо еще, если по какой-либо причине ваш запрос не завершился неудачно (например, недопустимый синтаксис), и в этом случае он может дать вам идентификатор вставки из предыдущего в том же соединении. Но не кто-то другой.