mysql可重複讀現象及原理分析
一、可重複讀
我們先看看現象,再分析原理。我的mysql版本是5.5。
下面是一張表,只有一條資料,並且我開啟了事物
此時,另乙個事物將record加1,因此我在開啟乙個命令列客戶端,執行下面的命令:
成功加1之後,實際上,資料庫中record肯定是2。
然後回到之前的客戶端,再查一次:
沒毛病,record還是1,果然是可重複讀。有些人以為mysql的可重複讀是通過行鎖實現的,
從上面可以知道,肯定不是,如果是的話,第一次select * from test的時候,id=1的記錄就會加行鎖,我都加行鎖了,我還沒提交,另外的事物是怎麼update成功的。
結論就是mysql使用的mvcc(多版本併發控制),mvcc詳解可以看:
我們繼續,我之前的第乙個事物還沒提交,不過提交之前,我也想加1;
加完之後我再查一下,額,record是3,好像很奇怪,但也不奇怪。
其實,update test set record=record+1 where id=1;這條語句中,在加1之前,他知道自己等於2,然後2+1=3。
也就是說,update時讀取資料是最新版本的資料,而select是到當前事物版本為止的資料。當更新成功之後,當前版本即為最新版本,再次select,讀取的是最新的資料。
在這裡討論下樂觀鎖的必要性。下面是樂觀鎖的實現,實現樂觀鎖,我們一般會這麼做
update test set record=record+1 where id=1 and record=1;
如果不用樂觀鎖,你用select讀取到的值其實根本不準確。除非你開啟悲觀鎖,像下面這樣:
select * from test where id=1 for update;
這樣可以讀取到最新的內容,同時在你當前的事物提交之前,其他事物的update此條記錄將會鎖等待。
故事到此,還沒有結束,此時我們開啟事物三,也做加1操作看會發生什麼。
結果是,鎖等待超時,也就是說(事物一)在更新完後,會加行鎖,這個應該比較好理解。事物中,剛開始查詢的時候是不會加行鎖的,但是當有更新操作之後,會加行鎖,直到事物提交。
因為事務一還沒有提交,所以事務三的select * from test;還只能查詢到事務二提交的結果,也就是record是2
然後因為事務一中對id=1這條資料進行了修改,所以mysql自動將這條資料開啟了行鎖,在事務一提交之前,任何事務不可以修改id=1這條資料
mysql可重複讀現象及原理分析 - mysql資料庫欄目 - 紅黑聯盟
mysql 可重複讀。
一 可重複讀 我們先看看現象,再分析原理。我的mysql版本是5.5。下面是一張表,只有一條資料,並且我開啟了事物 此時,另乙個事物將record加1,因此我在開啟乙個命令列客戶端,執行下面的命令 成功加1之後,實際上,資料庫中record肯定是2。然後回到之前的客戶端,再查一次 沒毛病,recor...
mysql可重複讀
mysql innodb的預設隔離級別是可重複讀,之前理解有些偏差,查閱一些資料後總結出幾點 首先有兩個概念 一致性檢視 當乙個事務開啟時,innodb會生成乙個檢視,這個檢視是邏輯檢視,通過undo log和row tranzaction id控制實現。在該事務的任何時間點,一致性檢視中的資料都是...
MySQL 的可重複讀
我在這裡分享一篇關於 mysql 的可重複讀介紹,講得挺好的,可以解決一些疑惑,鏈結在下方引用處。sql 1992 年標準關於幻讀 phantom 的解釋 乙個事務 t1 根據某些查詢條件 讀取某幾行資料,然後事務 t2 執行 sql 語句插入一行或多行滿足查詢條件 的資料 這時候如果事務 t1 重...