如何在PHP中处理查询同步?

如何在PHP中处理查询同步?,php,mysql,synchronization,Php,Mysql,Synchronization,我想在表中插入一些值,表中有一个自动递增字段作为主键。然后我想通过使用mysql\u insert\u ID()检索ID,并将此ID用作另一个表中的外键。问题是——尽管可能性很小——在第一次插入和随后的检索之间,可能会发生另一次插入第一个表的情况,因此会返回错误的ID PHP会自动处理这个问题,还是我的担心是正确的?如果是这样,我如何克服它们呢?是您所需要的。在MySQL中,InnoDB是唯一支持事务的引擎。MySQL\u insert\u id()将根据每个连接返回最后插入的id。因此,基本上

我想在表中插入一些值,表中有一个自动递增字段作为主键。然后我想通过使用
mysql\u insert\u ID()
检索ID,并将此ID用作另一个表中的外键。问题是——尽管可能性很小——在第一次插入和随后的检索之间,可能会发生另一次插入第一个表的情况,因此会返回错误的ID

PHP会自动处理这个问题,还是我的担心是正确的?如果是这样,我如何克服它们呢?

是您所需要的。在MySQL中,InnoDB是唯一支持事务的引擎。

MySQL\u insert\u id()将根据每个连接返回最后插入的id。因此,基本上,您不必担心并发脚本请求,如果您担心的话

供参考:

编辑:

顺便说一句,你可以很容易地测试这个

test.php

<?php

    $sleep = isset( $_GET[ 'sleep' ] ) ? true : false;

    $conn = mysql_connect( /* your parameters */ );
    mysql_select_db( /* your db */, $conn );

    $sql = 'INSERT INTO yourtable(id,col1,col2) VALUES(null,"test","test")';
    mysql_query( $sql );

    if( $sleep ) sleep( 5 );

    echo mysql_insert_id();
?>

有两种通用策略可用于确保此问题不会影响您。首先,您可以使用事务(正如另一位作者所指出的)

但是,从性能角度来看,手动跟踪Id号可能会更快。可以通过在数据库中使用全局id来实现这一点。使系统中的ID全局唯一的滚动编号

假设全局id为100,您知道需要6个id。然后将106写入全局id表中的全局id行。。。然后使用101作为第一个条目,即102数据点中的外键,依此类推。这大大提高了处理大型数据集时的性能

因此,如果您需要制作100个新插件,这可能是一个好主意。如果你一次只需要6个。。使用事务

正如jmucchiello在评论中所建议的那样。您可以使用Update语句来确保另一个进程没有写入全局id条目。差不多

更新globaltable集合id=106,其中id=100

我可以看到,我正在修改这个答案,但这确实是最好的策略,如果你有一百万行导入。。。哦,好吧


-FT

+1-我很确定php函数只是查询last_insert_id(),它说“生成的ID在服务器中按每个连接进行维护。这意味着函数返回给给定客户机的值是该客户机为影响自动增量列的最新语句生成的第一个自动增量值“@ryeguy:我也这么认为。我甚至相信PHP的mysql_insert_id()是C API的mysql_insert_id()的代理。(不完全确定,但我想我已经在其他PHP函数中看到了这一点,所以我不会感到惊讶)。我提到的MySQL文档中提到了C API函数。但是如果两个并发查询从数据库中检索到相同的全局ID(这可能会发生,因为读取、决定和重写不是一个原子操作)它们将开始使用相同的id,这在您需要唯一密钥时是不允许的。kahoon:update globaltable set id=106,其中id=100。假设这是整个事务(或者您使用的是不支持事务的mysql数据库)卡霍恩:正如jmuchhiello指出的,如果其他进程正在更新全局id,那么id将不会是100…并且不会有任何变化。当然,你需要检查一下你的查询结果是什么。令人惊讶的是,我在这个问题上被否决了,因为我的方法是可行的,如果不方便的话,而且我不是借口这不是什么不方便的事。哦,好吧。我不知道为什么会这样做(好吧,这是一个PHP问题…),但基本上——如果你有一个查询依赖于另一个查询的结果,你需要使用一个事务。其他任何事都是一个黑客行为。(不过,最后一个插入id是MySQL的特例。)不使用事务可能不是ACID,但这并不意味着它是一种黑客行为。有许多数据关系可以在不需要事务的情况下安全地进行操作。知道哪些可以和哪些不可以是一个不同的问题。但不要假设所有数据库应用程序都必须有事务。