[英]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 aBIGINT
(64-bit) value representing the first automatically generated value that was set for anAUTO_INCREMENT
column by the most recently executedINSERT
statement to affect such a column.LAST_INSERT_ID()
(不带参数)返回一个BIGINT
(64位)值,表示由最近执行的INSERT
语句为AUTO_INCREMENT
列设置的第一个自动生成的值,以影响此类列。 For example, after inserting a row that generates anAUTO_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 anAUTO_INCREMENT
value with one statement, and then refer toLAST_INSERT_ID()
in a multiple-rowINSERT
statement that inserts rows into a table with its ownAUTO_INCREMENT
column.假设您使用一个语句生成
AUTO_INCREMENT
值,然后在多行INSERT
语句中引用LAST_INSERT_ID()
,该语句将行插入到具有自己的AUTO_INCREMENT
列的表中。 The value ofLAST_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()
andLAST_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 ofLAST_INSERT_ID()
is left undefined.对于事务表,如果由于错误而回滚语句,则
LAST_INSERT_ID()
的值未定义。 For manual ROLLBACK, the value ofLAST_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.