9

我用 MySQL Server 5.5 试过这个:

1)确保事务隔离级别是repeatable_read

2)启动shell-1,在其中启动一个事务,然后通过select读取一个值

3)启动shell-2,在其中启动一个事务,然后通过select读取相同的值

4) 在 shell-1 中,将值更新为 value + 1 并提交

5) 在 shell-2 中,将值更新为 value + 1 并提交

该值丢失了一次更新,仅增加了 1。

现在,据我了解,RR 使用共享读锁和排他写锁,这意味着在上面的#4 和#5 中,事务应该是死锁的,但这并没有发生。

所以要么我对 RR 的理解有问题,要么 MySQL 以不同的方式实现 RR。那是什么?

编辑:通过类似的实验,还确认了一个 RR 事务 (t1) 看不到由另一个 RR 事务 (t2) 插入到同一个表中的行,如果它在该表上执行另一个选择,即使在 t2 提交之后和 t1 提交之前. (这里是这个实验的链接:http ://www.databasejournal.com/features/mysql/article.php/3393161/MySQL-Transactions-Part-II---Transaction-Isolation-Levels.htm )

这是否意味着 MySQL 的 RR 也负责幻读?

4

1 回答 1

8

MySQL 确实不符合可重复读取。您可以通过使用可序列化的隔离级别或在您的选择之后放置 FOR UPDATE 来强制它执行(请看下面的示例)。然后将实现所需的行为。关于幻读,MySQL实际上比必要的更严格......

SELECT value FROM table WHERE id = 7 FOR UPDATE;
于 2012-05-03T09:11:46.523 回答