2012-07-10 98 views
3

如果例如当用户点击一个链接,一个新行被自动插入,然后php代码请求最后插入的ID,并且在同时另一行被另一个用户插入,所以返回的ID实际上不是我期待的那个..?PDO + PHP lastInsertId()问题

我错了吗?没有这种“安全”漏洞,有没有办法做到这一点?
(也许从准备好的声明或其他内容...)

P.S id是自动生成的。

谢谢。

回答

3

要消除这种情况,您可以使用transaction

这将基本上隔离您的插入与其他人,所以只要您的插入/ lastInsertId()调用是在同一个事务中,它将工作得很好。

+0

所以它应该是这样的,对吧? :1)'$ dbh-> beginTransaction();'2)插入代码+'lastInsertId()'3)'$ dbh-> commit();' – Asaf 2012-07-10 13:11:35

+1

@xTCx正确;如果您在交易中做了什么错误,您也有可能“回滚”) – 2012-07-10 13:13:12

+0

好的,非常感谢您的帮助! – Asaf 2012-07-10 13:15:38

5

正如提到的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()始终是交易安全的(即使您不使用交易)。

+0

'lastInsertId()'由PDO驱动程序本身提供,并且可能是也可能不是SELECT'LAST_INSERT_ID();'的实际SQL查询。虽然这可能仍然是完全正确的,但基于这一点是绝对肯定的! – 2012-07-10 12:00:22