首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >隔离级别,不跳过任何数据。

问隔离级别,不跳过任何数据。
EN

Stack Overflow用户
提问于 2018-08-14 12:36:18
回答 1查看 68关注 0票数 2

假设我们想从MySQL (InnoDB)表event中读取新事件。我们记得我们看到的最后一个(自动增量) ID,并查询WHERE id > @LastSeenId。

如果ID 1到10可用,除了ID 4尚未提交外,怎么办?

显然,重要的是我们永远不要跳过任何可能存在的行。如果我们要跳过ID 4,我们将永远看不到它,并且将永远错过它,这是必须防止的。

我认为这取决于查询运行的隔离级别。

Serializable 1.我是否正确理解(以及其他级别)将提供所需的行为?

也就是说,它将等待任何影响与条件匹配的行(id > @LastSeenId)的未提交事务的提交/回滚?

更具体地说,如果我们没有显式地使用数据库事务,结果是否由默认的隔离级别决定?即使对于单个SELECT 查询?。

对于上下文,我们将使用官方的MySQL连接器来实现.NET。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-14 18:55:07

这是您可以用mysql客户端和两个窗口测试自己的东西。

打开窗口1,进入mysql客户端,创建一个表,并将提交的值填充它。

代码语言:javascript
复制
mysql1> use test;

mysql1> create table event (id serial primary key);

mysql1> insert into event values (1), (2), (3), (5);

现在开始一个超越。插入值4,如您的示例所示。

代码语言:javascript
复制
mysql1> begin;

mysql1> insert into event values (4);

请不要提交最后一次插入。

打开窗口2,进入mysql客户端,为会话设置事务隔离,并查询数据范围。

代码语言:javascript
复制
mysql2> use test;

mysql2> set tx_isolation = serializable;

mysql2> begin;

mysql2> select * from event where id >= 1;

选择在这个阶段挂起,等待。

这是因为在可序列化级别上,所有select查询都会隐式地尝试获取共享锁,就好像您在select查询的末尾添加了LOCK IN SHARE MODE (或FOR SHARE in MySQL 8.0语法)子句一样。这是一个锁读。它试图在id值的范围内获取一个间隙锁,但它还无法获得该锁,因为窗口1创建了一个未提交的行,该行位于该范围内。

现在,在窗口1中,提交事务(请确保在50秒后在窗口之前执行2次此操作):

代码语言:javascript
复制
mysql1> commit;

窗口2立即返回,现在它将看到完整的数据值集。

代码语言:javascript
复制
mysql2> select * from event where id >= 1;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
+----+

现在,尝试在窗口1中插入一个新行:

代码语言:javascript
复制
mysql1> begin;

mysql1> insert into event values (6);

现在这扇窗户挂起来了。为什么?因为它试图锁定正在插入的行,但是窗口2仍然在where id > 1行范围内持有一个间隙锁--其中包括新的值6。

这就是MySQL如何确保可重复读取的方式。它使用间隙锁来防止插入将进入其锁定范围的新行,因为新行将影响当前事务试图保留的行集。

最后,如果窗口2不完成其事务并释放其间隙锁,窗口1将超时:

代码语言:javascript
复制
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

所有这些都与自动增量无关。正如您在我的示例插入中所看到的,无论如何,我正在重写自动增量。它只与行和间隙上的锁有关,而不管这些行中的值是如何生成的。

我还必须指出,您要解决的问题本质上是一个发布/订阅模型,它更适合于消息队列技术,而不是关系数据库技术。您应该考虑使用消息队列作为RDBMS的补充技术。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51841585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档