資料庫 MVCC 和 樂觀鎖

2021-08-05 20:51:18 字數 1133 閱讀 1184

最近在看mysql的引擎型別,說到innodb時看到了mvcc,了解了一下。

mvcc全稱是multi-version concurrency control,多版本控制。什麼意思?說白了是解決資料庫讀-寫衝突的方法。資料庫不免要支援事務,事務acid的特性中的i,即隔離性就可以通過mvcc實現,就是說多個事務讀取資料時,需要隔離,只能讀到某一些值,比如已經提交的值,這就是保證事務隔離級別的方法。通過mvcc,可以在事務隔離型方面實現可重複讀的級別。具體時怎麼做的?每一行資料最後都會附加一些屬性,儲存的是最後更新這一行資料的事務的id和刪除這一行資料的id(這個刪除並不只是指那些delete操作,也包括了update,update實質是新插入一行,並且標記原有行為刪除,這樣才能讓某一些事務只能讀到以前的值),這個是乙個全域性的遞增的id,由資料庫來維護,這些都是不可見的。當乙個update的事務提交執行以後,通常是新增一行,然後附上自己的事務id,再標記之前的那行資料的刪除id。那麼讀事務執行時,只能讀取到同時滿足下面兩個條件的行:

(1)更新id小於等於當前id

(2)刪除id大於等於當前id

這樣首先可以保證read commited隔離級別,因為只有執行到commit才會被寫入資料庫中,也就是前面所說的在原有行下新增一行。所以讀到的資料都是已提交的。

然後,只能讀取「更新id小於等於當前id」可以保證repeatable read特性。read commited只能保證讀取到已提交的值,但是即使是比當前事務晚的事務做的更新,也可以讀取到。比如乙個讀事務很長,在最後一刻才執行讀,在該事務開始之後,在該事務讀操作執行之前,另乙個事務更新並且提交,該事務也可以讀到,因為它提交了。但這就引發了重複讀可能讀到不同值的風險,可能這個讀事務在最開始就已經讀了另乙個更早的更新事務更新的值,然後又發生了上述乙個新的更新事務,該讀事務又讀了該值,這時,讀取到的值就不同了。所以必須讓讀取事務只能讀取更新域id小於等於自己的行,即可以被其他事務修改,但是該更新事務必須在當前事物之前,也就是id小於等於。這是,發生在後面的更新事務所做的操作就會被隔離。這就是mvcc實現repeatable read的原理。

那麼mvcc聽起來和樂觀鎖類似啊,都有版本號這乙個概念,其實有區別。

樂觀鎖和mvcc處理的問題不同,樂觀鎖解決的是寫-寫衝突,只是它的機制是寫入不阻塞,如果衝突就只允許乙個,其他的回滾。所以我覺得樂觀鎖是處理事務acid的「c」的。

資料庫悲觀鎖和樂觀鎖簡述

鎖 locking 業務邏輯的實現過程中,往往需要保證資料訪問的排他性。如在金融系統的日終結算 處理中,我們希望針對某個 cut off 時間點的資料進行處理,而不希望在結算進行過程中 可能是幾秒種,也可能是幾個小時 資料再發生變化。此時,我們就需要通過一些機 制來保證這些資料在某個操作過程中不會被...

資料庫的悲觀鎖和樂觀鎖

資料庫的四種隔離級別 髒讀 不可重複讀 可重複讀 序列化,雖然四種隔離級別能夠處理事務問題,但是不夠靈活,於是有了悲觀鎖和樂觀鎖。悲觀鎖 對於外界的修改持保守態度,在整個資料處理中資料處於鎖定狀態。以mysql為例,select for update和lock in share model能夠實現悲...

資料庫的悲觀鎖和樂觀鎖

悲觀鎖就是對資料的衝突持悲觀態度,也就是假設資料肯定會發生衝突,所以在資料開始讀取的時候就把資料鎖定住。書籍表book,id為商品id 主鍵 isonline是否上線,1代表上線,0代表下線,那麼我們如果要對書籍進行下線,就需要將online置為0,假設id為1 如果不採用鎖 1 select fr...