PDO + PHP lastInsertId()问题
如果例如当用户点击一个链接,一个新行被自动插入,然后php代码请求最后插入的ID,并且在同时另一行被另一个用户插入,所以返回的ID实际上不是我期待的那个..?PDO + PHP lastInsertId()问题
我错了吗?没有这种“安全”漏洞,有没有办法做到这一点?
(也许从准备好的声明或其他内容...)
P.S id是自动生成的。
谢谢。
正如提到的manual:
LAST_INSERT_ID()
(无参数)返回一个表示由最用于AUTO_INCREMENT
列设置第一自动生成的值的BIGINT
(64位)的值最近执行了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()
的值不会恢复到交易前的值;它 保持原样,在ROLLBACK处。
因此,LAST_INSERT_ID()
始终是交易安全的(即使您不使用交易)。
'lastInsertId()'由PDO驱动程序本身提供,并且可能是也可能不是SELECT'LAST_INSERT_ID();'的实际SQL查询。虽然这可能仍然是完全正确的,但基于这一点是绝对肯定的! – 2012-07-10 12:00:22
在成功INSERT
后,MySQL服务器将插入ID作为OK
消息的一部分进行传输。该ID存储在PDO中,因此无需往返服务器,PDO就可以以安全的方式为您的连接返回正确的ID。
参考:http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#OK_Packet
所以它应该是这样的,对吧? :1)'$ dbh-> beginTransaction();'2)插入代码+'lastInsertId()'3)'$ dbh-> commit();' – Asaf 2012-07-10 13:11:35
@xTCx正确;如果您在交易中做了什么错误,您也有可能“回滚”) – 2012-07-10 13:13:12
好的,非常感谢您的帮助! – Asaf 2012-07-10 13:15:38