3

如果例如当用户单击链接时,会自动插入新行,然后php代码请求最后插入的id,同时另一个用户插入另一行,这不会有问题,所以返回的 id 实际上不是我所期望的..?

我错了吗?没有那个“安全”漏洞,有没有办法做同样的事情?
(比如可能来自准备好的声明或其他东西......)

PS id 是自动生成的。

谢谢你。

4

3 回答 3

5

手册中所述:

LAST_INSERT_ID()(不带参数)返回一个BIGINT(64 位)值,该值表示由最近执行的语句为列设置的第一个自动生成的值,以影响这样的列。例如,插入产生值的行后,可以这样获取值:AUTO_INCREMENT INSERTAUTO_INCREMENT

mysql>SELECT LAST_INSERT_ID();
    ->195

当前执行的语句不影响 的值 LAST_INSERT_ID()。假设您AUTO_INCREMENT使用一个语句生成一个值,然后LAST_INSERT_ID()在一个多行INSERT语句中引用,该语句将行插入到具有自己的AUTO_INCREMENT列的表中。的值LAST_INSERT_ID()将在第二个语句中保持稳定;它对第二行和后面的行的值不受早期行插入的影响。(但是,如果您混合对LAST_INSERT_ID()and的引用LAST_INSERT_ID(expr),则效果是不确定的。)

如果前面的语句返回错误,则 的值 LAST_INSERT_ID()未定义。对于事务表,如果语句由于错误而回滚,则 的值 LAST_INSERT_ID()未定义。对于手动ROLLBACK, LAST_INSERT_ID()不会恢复到交易前的值;它保持原样在ROLLBACK点。

因此,LAST_INSERT_ID()始终是事务安全的(即使您不使用事务)。

于 2012-07-10T11:32:25.913 回答
4

OKMySQL 服务器在成功后将插入 ID 作为消息的一部分传输INSERT。此 ID 存储在 PDO 中,因此无需往返服务器 PDO 就可以安全地为您的连接返回正确的 ID。

参考: http: //forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#OK_Packet

于 2012-07-10T12:35:08.197 回答
3

为了抵消这一点,您将使用事务

这基本上会将您的插入与其他插入隔离开来,因此只要您的插入/lastInsertId()调用在同一个事务中,它就可以正常工作。

于 2012-07-10T11:06:39.213 回答