MySQL可重复读取和丢失更新/幻像读取

时间:2012-04-06 08:02:27

标签: mysql transactions isolation-level

我尝试使用MySQL Server 5.5:

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

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

读取一个值

3)启动shell-2,在其中启动一个事务,然后通过select

读取相同的值

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

5)在shell-2中,将值更新为值+ 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还会处理幻像读取?

1 个答案:

答案 0 :(得分:8)

MySQL真的不符合Repeatable Read。您可以通过使用可序列化的隔离级别或在选择后放置FOR UPDATE来强制执行此操作(请参阅下面的示例)。然后将实现期望的行为。 关于幻像读取,MySQL实际上比必要更严格......

SELECT value FROM table WHERE id = 7 FOR UPDATE;