Mysql 是否可以对刚更新的行执行幻象读取?
从MySQL词汇表: 幻影:出现在查询的结果集中,但不出现在先前查询的结果集中的行。例如,如果一个查询在一个事务中运行两次,同时,另一个事务在插入新行或更新行以使其与查询的WHERE子句匹配后提交 粗体部分正确吗?如果我有Mysql 是否可以对刚更新的行执行幻象读取?,mysql,transactions,innodb,repeatable-read,Mysql,Transactions,Innodb,Repeatable Read,从MySQL词汇表: 幻影:出现在查询的结果集中,但不出现在先前查询的结果集中的行。例如,如果一个查询在一个事务中运行两次,同时,另一个事务在插入新行或更新行以使其与查询的WHERE子句匹配后提交 粗体部分正确吗?如果我有 CREATE TABLE t1 ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `c1` varchar(45) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB; 隔离
CREATE TABLE t1 (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`c1` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
隔离级别是可重复读取的,我是这样做的
mysql> start transaction;
mysql> SELECT * FROM t1 WHERE c1 < 10;
+----+------+
| id | c1 |
+----+------+
| 1 | 4 |
+----+------+
mysql> SELECT * FROM t1 WHERE c1 < 10;
+----+------+
| id | c1 |
+----+------+
| 1 | 4 |
+----+------+
mysql>启动事务;
mysql>从t1中选择*其中c1<10;
+----+------+
|id | c1|
+----+------+
| 1 | 4 |
+----+------+
mysql>从t1中选择*其中c1<10;
+----+------+
|id | c1|
+----+------+
| 1 | 4 |
+----+------+
有时,即使没有人做任何插入,而只做更新,我也会从后面的查询中得到不同的结果?我的MySQL版本是5.7
SQL标准指出幻象读取仅与并发插入相关,尽管单词generate有点混乱。根据ISO/IEC 9075:1992,数据库语言SQL-1992年7月30日(第二次非正式审查草案):
P3(“幻影”):SQL事务T1读取满足某些搜索条件的行N的集合。SQL事务T2然后执行SQL语句,这些语句生成满足SQL事务T1使用的搜索条件的一行或多行。如果SQL事务T1然后使用相同的搜索条件重复初始读取,它将获得不同的行集合
据我所知,在使用可重复读取的事务中,不可能(不应该?)获得幻影行
在可重复读取锁中创建事务时,mysql会在事务中的第一个查询运行后创建数据的“快照”
因此,任何select语句都将获取该快照中的数据
据我所知,文档中的两个警告可能会导致意外结果:
SELECT
语句(这可能不是意外的,但我认为可能会造成混乱)我很想知道,在你的情况下,你是否有一个不同的环境造成了这种情况!链接的任何文档都澄清了这一点吗?如果这是一个相当“深入”的mysql问题,那么DBA堆栈交换可能是一个更好的尝试。InnoDB REPEATABLE-READ事务隔离级别可以防止虚行,但前提是SELECT查询是非锁定查询 因此,您可以在一个事务期间多次使用相同的查询条件进行选择,并且可以保证一次又一次地获得相同的结果,即使其他会话正在以可能影响结果集的方式插入、更新或删除行。一旦您开始一个新的事务,您的查询就会看到同时对行所做的更改 但InnoDB有一个奇怪的情况:如果您运行类似以下之一的:
SELECT * FROM t1 WHERE c1 < 10 FOR UPDATE
SELECT * FROM t1 WHERE c1 < 10 LOCK IN SHARE MODE
SELECT * FROM t1 WHERE c1 < 10 FOR SHARE -- MySQL 8.0 syntax
从t1中选择*其中c1<10用于更新
从t1中选择*其中c1<10锁定在共享模式下
从t1中选择*其中c1<10表示SHARE--MySQL 8.0语法
然后,SELECT将“查看”并发数据更改的结果,就好像您的事务已作为一个读提交事务启动一样
在同一个可重复读取事务中,您甚至可以在锁定读取查询和非锁定读取查询之间来回切换,您将看到每个查询的不同结果集。因此,如果使用锁定SELECT语句,请注意这一点
我认为你展示的摘录中的“生成”一词是指插入或更新。他们需要一个术语来适用于这两种情况,因为我想他们不想写一个更清晰的短语,如“插入或更新”。这就是你要找的?答案是我的:)但从2011年开始。可能是因为我写了这篇文章后发生了一些变化。可以自由发表新的答案和评论。@Danielrera我还不能给你的文章写评论,但很容易在阅读提交级别上产生幻影行,因此文章的一部分肯定是错误的。此外,第二个投票最多的答案有一个关于可重复读取级别的幻影行的示例,尽管我不确定这些行是真正的幻影行还是它们被称为其他行。