php - 执行 MySQL 查询期间字段是否可以更改并且两个值都出现在结果集中?

标签 php mysql

我遇到了一些奇怪的防御代码。基本上它执行这样的查询:

select * from A join B on (A.b_id=B.id)

然后它会迭代结果集,每当遇到表 B 中的新行时,它都会将其缓存(通过 id)。之后,即使对于后续行,也仅使用缓存的副本。

看起来它试图防止出现这样的结果集:

 A.id | A.value | B.id | B.value
------+---------+------+---------
 1    | First   | 1    | Yay
 2    | Second  | 1    | Nay

但这可能吗?即使在 select 查询半途获取时表 B 中的行被更新,它真的会可见吗?当有人查询表时更新还能继续吗?

就其值(value)而言,我认为当时的表是 MyISAM,尽管后来它已转换为 InnoDB。此外,运行查询的代码是用 PHP 编写的。据我所知,它使用默认的事务隔离级别和获取模式。


好吧,看来我需要一些澄清。这是一段代码,与我发现的类似:

$sql = "select A.id a_id, A.value a_value, B.id b_id, B.value b_value from A join B on (A.b_id=B.id)";
$res = mysql_query($sql);
$cacheB = array();
$A = new classA();
$B = new classB();
while ($row = mysql_fetch_assoc($res)) {
    $A->setData($row);
    if ( !isset($cacheB[$row['b_id']]) ) {
        $cacheB[$row['b_id']] = $row;
    }
    $B->setData($cacheB[$row['b_id']]);

    // Do some processing depending on $A and $B
}

此代码是从 cron 作业运行的 CLI 应用程序。 $A$B 中的数据不会返回任何内容,但根据内容,可能会调用一些外部服务,并且可能会修改一些其他数据库表。 classAclassB的内容及处理与本题无关。

我的问题是——这个“保障”有没有意义,或者是一个可以删除的负担?我们假设处理部分实际上对 B 值的变化敏感(尽管实际上我对此表示怀疑,但仍然如此)。

最佳答案

Can a field change during the execution of a MySQL query and both values be present in the result set?

没有。

  • 在 MyISAM 中,每个查询都会锁定整个表,因此设计上根本不可能(请参阅 table locking)。
  • 在 InnoDB 中,查询是隔离的,选择是一致的读取,如文档 Locks Set by Different SQL Statements in InnoDB 中所述。 。 一致性读取被定义为“使用快照信息基于某个时间点呈现查询结果的读取操作,而不管同时运行的其他事务执行的更改如何。” em>”

Even if the row in table B is updated while the select query is fetched half way, will it really be visible?

是的,即便如此,这也是不可能的。

Can the update even proceed while someone is querying the table?

在 MyISAM 中,不,它必须等待,正如文档中所解释的:“表锁定使许多 session 能够同时从表中读取,但是如果一个 session 想要写入表,它必须首先获得独占访问权限,这意味着它可能必须等待其他 session 首先完成该表。在更新期间,所有其他想要访问此特定表的 session 必须等待更新完成。"

在 InnoDB 中是的,但是查询是隔离的,并且按照解释在数据库的不同“快照”上工作,所以这并不重要。如果您有任何疑问,交易在这种情况下特别有用。

您显示的代码可能有也可能没有其他目的,这一点我不能说。但如果它的唯一目的是防止不可能发生的事情发生,那么它就完全多余了,可以安全地删除。

关于php - 执行 MySQL 查询期间字段是否可以更改并且两个值都出现在结果集中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48226707/

相关文章:

php - PHP 的 hex2bin 函数的 ColdFusion 替代方案

MYSQL 语法连接

c# - 在 Windows 10 更新 1803 之后,我的程序在从网络共享运行时无法打开套接字

php - mysql 语法错误,无法检测到它的位置 :

php - 如何将生成的 MySQL 行存储到数组中?

javascript - PHP/AJAX - 在 PHP 中使用 $_FILES 访问 javascript 文件数组

php - 无法让 PHP 从 mySQL 中提取行条目作为数组

javascript - jquery中通过循环获取值

mysql - 子查询在 mysql 中返回多于 1 行

mysql - zend framework 从两个表中获取数据