如果例如当用户点击一个链接时,会自动插入一个新的行,然后php代码请求最后插入的id,同时另一个用户插入另一行,那么返回的id实际上不是我期望的id,这难道不是问题吗?
我说错了吗?有没有办法在没有“安全”漏洞的情况下做到这一点?
(例如,可能来自准备好的语句或其他内容...)
附注: id是自动生成的。
谢谢。
发布于 2012-07-10 19:06:39
为了解决这个问题,你可以使用一个transaction。
这基本上将您的插入与其他插入隔离开来,因此,只要您的Insert/lastInsertId()调用在同一事务中,它就会正常工作。
发布于 2012-07-10 19:32:26
正如在manual中提到的
LAST_INSERT_ID()(不带参数)返回一个BIGINT(64位)值,表示由最近执行的AUTO_INCREMENT语句为INSERT列设置的第一个自动生成的值,以影响此类列。例如,在插入生成AUTO_INCREMENT值的行之后,您可以获得如下所示的值:
mysql>SELECT LAST_INSERT_ID();->195
当前执行的语句不会影响LAST_INSERT_ID()的值。假设您用一条语句生成一个AUTO_INCREMENT值,然后在一个多行INSERT语句中引用LAST_INSERT_ID(),该语句将行插入到具有自己的AUTO_INCREMENT列的表中。在第二条语句中,LAST_INSERT_ID()的值将保持稳定;它在第二行和后面行的值不受前面的行插入操作的影响。(但是,如果混合引用LAST_INSERT_ID()和LAST_INSERT_ID(expr),则效果未定义。)
如果上一条语句返回错误,则LAST_INSERT_ID()的值未定义。对于事务性表,如果语句由于错误而被回滚,则LAST_INSERT_ID()的值将保持未定义状态。对于手动回滚,LAST_INSERT_ID()的值不会恢复到事务之前的值;它将保持在点上的值。
因此,LAST_INSERT_ID()始终是事务安全的(即使您不使用事务)。
发布于 2012-07-10 20:35:08
MySQL服务器在INSERT成功后将插入ID作为OK消息的一部分进行传输。此ID存储在PDO中,因此无需往返于服务器PDO即可安全地为您的连接返回正确的ID。
参考:http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#OK_Packet
https://stackoverflow.com/questions/11411938
复制相似问题