2012-04-06 75 views
8

我试图与MySQL服务器5.5:MySQL的重复读取和更新丢失/幻读

1)保证事务隔离级别是REPEATABLE_READ

2)开始壳1,在它开始交易,然后读取通过选择

3)开始壳2的值,在它开始一个事务,然后读取通过在壳1选择

4)相同的值,更新值到值+ 1,并致力于

5)在壳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也照顾了幻影读取?

+0

您是否尝试过序列化事务? http://dev.mysql.com/doc/refman/5.1/en/set-transaction.html#isolevel_serializable – biziclop 2012-04-06 08:24:27

+0

是的,它看起来像MySQL序列化使用共享读取锁定和独占写入锁定,因此在以上情况。所以我非常困惑,因为这里是'JP with Hibernate'一书的内容:“一个以可重复读取隔离模式运行的系统既不允许重复读取,也不允许读取脏读,可能会发生幻像读操作 写块事务其他阅读交易),并写入交易阻止所有其他交易。“ (第456页) – shrini1000 2012-04-06 08:30:45

回答

6

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

SELECT value FROM table WHERE id = 7 FOR UPDATE; 
+0

thx!你可以套住吗?引用这个参考,所以我可以接受它作为答案? – shrini1000 2012-05-03 09:50:22

+4

http://www.cs.umb.edu/~poneil/iso.pdf指出在重复读取中丢失更新是不可能的。你可以在最后一页找到总结,并在中间某个地方讨论特定的异常(只需搜索“丢失的更新”)。我不能给你更多的参考,我希望现在已经足够了。 – Argeman 2012-05-03 10:46:49

+0

可以肯定的是:当使用带有可重复读取功能的InnoDB时,丢失的更新实际上是可行的,因为它们的不符合实现。是对的吗? – Basti 2015-07-10 10:00:37