MySQL 和 PDO:理论上 PDO::lastInsertId 会失败吗?

Posted

技术标签:

【中文标题】MySQL 和 PDO:理论上 PDO::lastInsertId 会失败吗?【英文标题】:MySQL and PDO: Could PDO::lastInsertId theoretically fail? 【发布时间】:2011-08-21 07:55:49 【问题描述】:

我一直在思考这个问题。

考虑一个庞大的网络应用程序,比方说,每秒执行数百万个 SQL 查询。

我运行我的代码:

$q = $db->prepare('INSERT INTO Table
                 (First,Second,Third,Fourth)
          VALUES (?,?,?,?)');
$q->execute(array($first,$second,$third,$fourth));

紧接着,我想获取最后一个查询的自动递增 ID:

$id = $db->lastInsertId();

lastInsertId 是否有可能失败,即获取在我的两个代码块之间执行的某些 SQL 插入查询的 ID?

中学:

如果它可能失败,那么堵住这种可能的泄漏的最佳方法是什么?

创建另一个 SQL 查询以从数据库中获取正确的 ID 会更安全吗?

【问题讨论】:

【参考方案1】:

只要 PDO 实现没有做一些真正愚蠢的事情,它总是安全的。以下来自last_insert_id上的mysql信息:

生成的 ID 在每个连接的基础上在服务器中维护。这意味着函数返回给给定客户端的值是为影响该客户端的 AUTO_INCREMENT 列的最新语句生成的第一个 AUTO_INCREMENT 值。此值不受其他客户端的影响,即使它们生成自己的 AUTO_INCREMENT 值。这种行为确保每个客户端都可以检索自己的 ID,而无需担心其他客户端的活动,也不需要锁或事务。

【讨论】:

【参考方案2】:

没有。 lastInsertId 是每个连接的,不需要向服务器发出请求 - mysql 总是在其响应数据包中将其发送回。

所以如果execute方法没有抛出异常,那么就保证你在lastInsertId中有正确的值。

它永远不会为您提供其他任何内容的插入 ID,除非您的查询由于某种原因(例如无效语法)失败,在这种情况下,它可能会为您提供同一连接上前一个查询的插入 ID。但不是其他人的。

【讨论】:

真棒马克,那我就放心了:)

以上是关于MySQL 和 PDO:理论上 PDO::lastInsertId 会失败吗?的主要内容,如果未能解决你的问题,请参考以下文章

在docker上使用laravel时无法连接到mysql数据库(未找到,pdo,连接被拒绝)

PHP中的MySQLi扩展学习mysqli的事务与预处理语句

PDO数据访问抽象层(上)

如果 PDO 和 mysqli 不可用,使用 mysql_* 函数是不是安全?

启用 mcrypt、soap 和 pdo_mysql

使用 PHP 5.5 在 Amazon EC2 上安装 pdo_mysql