mysqli_fetch_assoc - 如果同时更改数据会发生什么?

时间:2011-08-14 16:36:42

标签: php mysqli

在PHP中,我在while循环中使用mysqli_fetch_assoc()来获取特定查询中的每条记录。

我想知道如果在运行循环(由另一个进程或服务器)中数据更改会发生什么,以便记录不再与查询匹配。它还会被取出吗?

换句话说,当您执行query()时,是否已修复获取的记录数组?或者不是吗?


更新

我知道这是一个功能,当数据发生变化时,结果集不会被更改,但是如果你真的想要这样做呢?在我的循环中,我对已经由另一台服务器更新的记录不感兴趣。如何检查,而不对我获取的每条记录执行新查询?

更新:

详细说明:

我正在研究某种搜索数据库中的值的搜索引擎。这是由几个服务器同时完成的。不应再搜索已经刮过的项目。我无法真正控制哪个服务器搜索哪个项目,我希望我可以在获取记录集时检查项目的状态。由于它是一个大数据集,我不会在搜索之前传输整个结果集,我会在需要时获取每条记录...

1 个答案:

答案 0 :(得分:3)

简介

  

我想知道如果在运行循环时(由另一个进程或服务器)更改数据会发生什么,以便记录不再与查询匹配。它还会被取出吗?

  

换句话说,当你执行query()时,获取的记录数组是固定的吗?或者不是吗?

如果在表更新和查询结果集迭代之间容易受到竞争条件的影响,那么DBMS就不值得了。

当然,就数据库本身而言,您的SELECT查询已经完成,然后才能更改任何数据;结果集缓存在数据库和PHP脚本之间的层中。


深入

关于the ACID principle *:

  

在数据库的上下文中,对数据的单个逻辑操作称为事务。

用户发起的TRANSACTION可以包含几个连续的查询,但ISO / IEC 9075-2中的4.33.4和4.33.5描述了这是如何在每个查询级别上隐式发生的:

  

以下SQL语句是事务启动的   SQL语句,即,如果没有当前的SQLtransaction,则为   执行此类的SQL语句,然后执行SQL事务   通常在执行该SQL语句之前启动:

     
      
  • 所有SQL-schema声明   
        
    • 以下SQL-transaction声明:
    •   
    • <start transaction statement>
    •   
    • <savepoint statement>
    •   
    • <commit statement>
    •   
    • <rollback statement>
    •   
  •   
  • 以下SQL-data声明:   
        
    • [..]
    •   
    • <select statement: single row>
    •   
    • <direct select statement: multiple rows>
    •   
    • <dynamic single row select statement>
    •   
    • [..]
    •   
  •   
  • [..]
  •   

另外,4.35.6:

  

SQL事务中SQL语句的影响

     

在SQL事务中执行SQL语句没有   对SQL数据或模式的影响[..]。加上可序列化   执行,这意味着所有读取操作都是可重复的   在隔离级别为SERIALIZABLE的SQL事务中,除外   为:

     

1)更改SQL数据或模式及其内容的影响   由SQL事务本身显式

     

2)提供给外部调用的SQL参数值差异的影响   程序

     

3)引用时变系统的影响   变量,如CURRENT_DATE和CURRENT_USER。


您更广泛的要求

  

据我所知,这是一项功能,即在更改数据时不会更改结果集,但如果您真的想要这样做会怎么样?在我的循环中,我对已经由另一台服务器更新的记录不感兴趣。如何检查,而不对我获取的每条记录执行新查询?

你可能没有。

虽然您可以控制连接器执行的缓冲类型(在本例中为MySQLi),但您无法覆盖上述SQL的低级事实: no INSERT或{{1或UPDATE会对正在进行的DELETE 产生影响。

SELECT完成后,结果是独立的;它是您可以控制的这种独立数据传输的缓冲,但这并不能帮助您做您想要做的事情。

坦率地说,这是相当幸运的,因为你想做的事听起来很奇怪!


*严格来说,MySQL has only partial ACID-compliance表示非默认存储引擎InnoDB,BDB和Cluster以及MyISAM does not support [user-instigated] transactions以外的表。不过,似乎“我”应该仍然适用于此;否则,MyISAM基本上没用。