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.

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

Другие вопросы по тегам