2012-04-06 42 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