简体   繁体   English

PDO + PHP lastInsertId()问题

[英]PDO + PHP lastInsertId() issue

Wouldn't there be a problem with it if for example when a user clicks on a link, a new row is automatically inserted and then the php code requests the last inserted id, and at the same time another row is inserted by another user, so the returned id is actually not the one I'm expecting..? 如果例如当用户点击链接,自动插入新行然后php代码请求最后插入的id,同时另一个用户插入另一行时,它不会有问题吗?所以返回的id实际上不是我期待的那个..?

Am I wrong? 我错了吗? Is there a way to do the same without that 'security' hole? 没有“安全”漏洞,有没有办法做同样的事情?
(like maybe from within the prepared statement or something...) (可能来自准备好的声明或其他内容......)

PS the id is automatically generated. PS自动生成id。

Thank you. 谢谢。

As mentioned in the manual : 手册中所述:

LAST_INSERT_ID() (with no argument) returns a BIGINT (64-bit) value representing the first automatically generated value that was set for an AUTO_INCREMENT column by the most recently executed INSERT statement to affect such a column. LAST_INSERT_ID() (不带参数)返回一个BIGINT (64位)值,表示由最近执行的 INSERT语句为AUTO_INCREMENT列设置的第一个自动生成的值,以影响此类列。 For example, after inserting a row that generates an AUTO_INCREMENT value, you can get the value like this: 例如,在插入生成AUTO_INCREMENT值的行后,您可以获得如下值:

 mysql>SELECT LAST_INSERT_ID(); ->195 

The currently executing statement does not affect the value of LAST_INSERT_ID() . 当前正在执行的语句不会影响LAST_INSERT_ID()的值。 Suppose that you generate an AUTO_INCREMENT value with one statement, and then refer to LAST_INSERT_ID() in a multiple-row INSERT statement that inserts rows into a table with its own AUTO_INCREMENT column. 假设您使用一个语句生成AUTO_INCREMENT值,然后在多行INSERT语句中引用LAST_INSERT_ID() ,该语句将行插入到具有自己的AUTO_INCREMENT列的表中。 The value of LAST_INSERT_ID() will remain stable in the second statement; LAST_INSERT_ID()的值将在第二个语句中保持稳定; its value for the second and later rows is not affected by the earlier row insertions. 它的第二行和后一行的值不受先前行插入的影响。 (However, if you mix references to LAST_INSERT_ID() and LAST_INSERT_ID(expr) , the effect is undefined.) (但是,如果混合对LAST_INSERT_ID()LAST_INSERT_ID(expr)引用,则效果未定义。)

If the previous statement returned an error, the value of LAST_INSERT_ID() is undefined. 如果前一个语句返回错误,则LAST_INSERT_ID()值未定义。 For transactional tables, if the statement is rolled back due to an error, the value of LAST_INSERT_ID() is left undefined. 对于事务表,如果由于错误而回滚语句,则LAST_INSERT_ID()的值未定义。 For manual ROLLBACK, the value of LAST_INSERT_ID() is not restored to that before the transaction; 对于手动ROLLBACK, LAST_INSERT_ID()值不会恢复到事务之前的值; it remains as it was at the point of the ROLLBACK . 它仍然像ROLLBACK那样

So, LAST_INSERT_ID() is always transaction-safe (even though you don't use transaction). 因此, LAST_INSERT_ID()始终是事务安全的(即使您不使用事务)。

The MySQL Server transfers the insert ID as part of the OK message after a successful INSERT . 成功INSERT后,MySQL Server将插入ID作为OK消息的一部分进行传输。 This ID is stored in PDO, therefore without a round-trip to the server PDO can return you the correct ID for your connection in a safe way. 此ID存储在PDO中,因此无需往返服务器PDO可以安全地为您的连接返回正确的ID。

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

To counteract this you would use a transaction . 要抵消这种情况,您将使用交易

This would essentially isolate your insert from others, so as long as your Insert/ lastInsertId() call is within the same transaction, it will work just fine. 这实际上会将您的插入与其他插入隔离,因此只要您的Insert / lastInsertId()调用在同一个事务中,它就可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM