在PHP中,我在while循环中使用mysqli_fetch_assoc()
来获取特定查询中的每条记录。
我想知道如果在运行循环(由另一个进程或服务器)中数据更改会发生什么,以便记录不再与查询匹配。它还会被取出吗?
换句话说,当您执行query()
时,是否已修复获取的记录数组?或者不是吗?
我知道这是一个功能,当数据发生变化时,结果集不会被更改,但是如果你真的想要这样做呢?在我的循环中,我对已经由另一台服务器更新的记录不感兴趣。如何检查,而不对我获取的每条记录执行新查询?
的更新: 的
详细说明:
我正在研究某种搜索数据库中的值的搜索引擎。这是由几个服务器同时完成的。不应再搜索已经刮过的项目。我无法真正控制哪个服务器搜索哪个项目,我希望我可以在获取记录集时检查项目的状态。由于它是一个大数据集,我不会在搜索之前传输整个结果集,我会在需要时获取每条记录...
答案 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基本上没用。