Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 我可以使用PDO执行并发请求和修改吗_Php_Pdo - Fatal编程技术网

Php 我可以使用PDO执行并发请求和修改吗

Php 我可以使用PDO执行并发请求和修改吗,php,pdo,Php,Pdo,我有一个mysql表,里面有很多数据。该表中的所有行都需要修改一个字段,而这种修改方式不容易用纯SQL表示 我希望能够逐行循环表,并逐个更新所有条目。 然而,要做到这一点,我会做如下事情: $sql = "SELECT id,value FROM objects"; foreach ($dbh->query($sql) as $row) { $value = update_value( $row['value'] ); $id = $row['id']; $upda

我有一个mysql表,里面有很多数据。该表中的所有行都需要修改一个字段,而这种修改方式不容易用纯SQL表示

我希望能够逐行循环表,并逐个更新所有条目。 然而,要做到这一点,我会做如下事情:

$sql = "SELECT id,value FROM objects";
foreach ($dbh->query($sql) as $row)
{
    $value = update_value( $row['value'] );
    $id = $row['id'];
    $update_sql = "UPDATE objects SET value='$value' WHERE id=$d";
    $dbh->query( $update_sql );
}
这会有什么坏处吗?(除了潜在的缓慢?)

澄清:我特别担心的是第一次使用光标进行选择,而不是在foreach中一次检索所有数据,然后 关于循环内部的更新导致的游标无效,我不知道有什么。如果有一些规则,比如“在用另一个光标扫描时不要更新同一个表”,那么它很可能只会出现在巨大的表上,因此我执行一个小测试用例是非常无用的


如果有人能告诉我这样做是可以的,而不是这样做的特殊问题,那也太好了。

看起来你有两个选择:

  • (直截了当):在开始循环之前,使用类似“fetchAll”的方法获取第一个查询的所有结果。这将有助于防止光标重叠
  • (更模糊):将此更改为使用存储函数(代替“update_value”),以便可以将两个查询转换为单个“update objects set value=some_function(id)”

  • 根据此操作的大小和持续时间,您可能需要事先锁定所有内容

    单个查询的结果是一致的,因此更新不会影响它。要记住:

  • 使用事先准备好的报表;它将减少进程和数据库之间的通信量,因为每次只传输值,而不是整个查询

  • 如果您担心其他进程同时运行,您应该使用事务和适当的锁定,例如

    // transaction started
    SELECT id,value 
    FROM objects 
    LOCK IN SHARE MODE
    
    // your other code
    
    // commit transaction
    

  • 它是在后台运行的一次性操作还是根据用户请求执行的实时操作?它是与应用程序架构更改相关的一次性功能。应用程序的其余部分将在运行时关闭。速度在这里并不是一个主要的问题。那么,你什么时候遇到了什么问题?我想如果只运行此代码而不是将其发布到此处,您应该已经完成了操作:)每个数据库可能只运行一次,但它确实需要在数百个数据库上运行,有些小,有些大,有些在这里,有些在那里。。。我不想巧妙地破坏它们中的任何一个,也不想错过迁移某些条目。我能想到的两个潜在问题是,在这个过程运行时,有其他东西正在更新同一个表。若这是一种可能性,那个么您可能应该锁定表,然后运行进程,然后解锁表。另一个问题是,如果在这个过程中间有些东西失败了,你会得到一些更新和一些不更新的结果。要处理这种情况,您需要使用事务beginTransaction()、更新所有行、endTransaction()