可重复读取和第二次丢失更新问题

发布于 2024-12-29 11:14:34 字数 300 浏览 4 评论 0 原文

使用可重复读隔离级别,仍然有可能丢失更新(第二个丢失更新问题)。例如,在隔离级别设置为 RR 的场景中:

1) 事务 t1 从行 r1 读取数据,

2) 事务 t2 从行 r1 读取相同的数据,

3) t1 修改 #1 中读取的数据并将数据提交到 r1

4) t2修改 #2 中读取的数据并将数据提交到 r1。 t1 的更新丢失

我用 Hibernate 尝试了此操作(隔离级别设置为 RR),并看到了如上所述的行为。

那么为什么说通过 RR 隔离我们不会出现第二次丢失更新问题呢?

With repeatable read isolation level, it is still possible to lose updates (second lost updates problem). E.g. in the scenario with isolation level set to RR:

1) transaction t1 reads data from row r1,

2) transaction t2 reads same data from row r1,

3) t1 modifies the data read in #1 and commits data to r1

4) t2 modifies the data read in #2 and commits data to r1. t1's update is lost

I tried this with Hibernate (isolation level set to RR) and saw the behavior as mentioned above.

Why then is it said that with RR isolation we do not get second lost updates problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱,才寂寞 2025-01-05 11:14:34

您可以推断出,在您在此测试中使用的 MySQL 版本中,实现并不真正符合可重复读取,就像您在其他问题中所说的那样,因为如果你已经做了

事务 t2 从 r1 行读取相同的数据

事务 t2在步骤 4 中再次

而不是

t2修改#2中读取的数据并将数据提交给r1。

那么 t2 就会读取 t1 在步骤 3 中保存的值。
所以你一开始就没有可重复读,所以不属于可重复读丢失更新的情况。

ANSI SQL-92 根据现象定义隔离级别:脏
读取、不可重复读取和幻像。

而不是像您一开始所想的那样当您说

现在,据我了解,RR使用共享读锁和独占写

这是因为

ANSI SQL 隔离设计者寻求一个可以容纳许多人的定义
不同的实现,而不仅仅是锁定。

事实上,一个例子是 READ_COMMITED 实现SQL 服务器

如果 READ_COMMITTED_SNAPSHOT 设置为 OFF(默认值),数据库
引擎使用共享锁来防止其他事务修改
当前事务正在运行读取操作时的行。 [...]

如果 READ_COMMITTED_SNAPSHOT 设置为 ON,数据库引擎将使用行
版本控制以呈现事务上一致的每个语句
语句开始时存在的数据快照。
锁不用于保护数据不被其他人更新
交易

丢失的更新不是这种现象之一,而是在对 ANSI SQL 隔离级别的批评中 Argeman在另一个问题解释了可重复读取保证不丢失更新:

P1 = 不可重复读取
P4 = 丢失更新
P2 的宽松解释(指定可能导致
到异常)是

P2: r1[x]...w2[x]...((c1 or a1) and (c2 or a2) in any order)

P2 的严格解释(指定实际异常),称为 A1 是

A2: r1[x]...w2[x]...c2...r1[x]...c1

而丢失更新的解释是

P4: r1[x]...w2[x]...w1[x]...c1

您提出的情况采用以下形式:

A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2

乍一看,这似乎是一种情况,但并不具有不可重复读取,事实上 t1 将始终在整个事务中读取相同的 x 值。

但如果我们关注 t2 并反转数字,我们可以看到这显然是不可重复读取的情况。

A4:r1[x]...r2[x]...w1[x]...c1...w2[x]...c2

A4: r1[x]...w2[x]...c2...w1[x]...c1(数字反转以提高可读性)

P2:r1[x]...w2[x]...((c1或a1)和(c2或a2)以任意顺序)< /p>

You can deduce that in the version of MySQL that you used in this test, the implementation doesn't really conform to Repeatable Read, like you say in your other question, because if you have done

transaction t2 reads same data from row r1

again in the step 4 instead of

t2 modifies the data read in #2 and commits data to r1.

then the t2 would have read it the value saved by t1 in the step 3.
So you don't have repeteable read at first, so it is not a case of repeteable read with lost update.

ANSI SQL-92 defines Isolation Levels in terms of phenomena: Dirty
Reads, Non-Repeatable Reads, and Phantoms.

and not in terms of locks like you thought at first when you said

Now, as I understand it, RR uses shared read locks and exclusive write
locks

This is because

ANSI SQL Isolation designers sought a definition that would admit many
different implementations, not just locking.

In fact one example of this is the READ_COMMITED implementation from SQL SERVER.

If READ_COMMITTED_SNAPSHOT is set to OFF (the default), the Database
Engine uses shared locks to prevent other transactions from modifying
rows while the current transaction is running a read operation. [...]

If READ_COMMITTED_SNAPSHOT is set to ON, the Database Engine uses row
versioning to present each statement with a transactionally consistent
snapshot of the data as it existed at the start of the statement.
Locks are not used to protect the data from updates by other
transactions
.

The lost updates is not one of this phenomena, but in A Critique of ANSI SQL Isolation Levels pointed out by Argeman in the other question is explained that repeteable read guarantees no lost updates:

P1 = Non-repeteable reads
P4 = Lost updates
The loose interpretation of P2 (specifies a phenomenon that might lead
to an anomaly) is

P2: r1[x]...w2[x]...((c1 or a1) and (c2 or a2) in any order)

The strict interpretation of P2 (specifies an actual anomaly), called A1 is

A2: r1[x]...w2[x]...c2...r1[x]...c1

While the interpretation of lost updates is

P4: r1[x]...w2[x]...w1[x]...c1

The case that you present is in the form of:

A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2

At first it seems that is a case that doesn't have non-repeteable reads, in fact the t1 will always read the same value of x along the whole transaction.

But if we focus on the t2 and invert the numbers we can see that is clearly a case of non-repeteable read.

A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2

A4: r1[x]...w2[x]...c2...w1[x]...c1 (with the numbers inverted for better readability)

P2: r1[x]...w2[x]...((c1 or a1) and (c2 or a2) in any order)

み零 2025-01-05 11:14:34

我已经用 MySQL 尝试了上述实验,看起来 MySQL 实现了不同的 RR 概念: MySQL可重复读和丢失更新/幻读

I had tried the above experiment with MySQL, and looks like MySQL implements a different notion of RR: MySQL repeatable read and lost update/phantom reads

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文