理解mysql的事務隔離級別

小強Zzz發表於2022-03-01

前言

考研分數落定,今年無緣,著手準備春招。說到今年考研,分數可謂水漲船高,去年本校專碩270就能進,今年一舍友考了270,排名排到了140名(報的專業要70個),進複試基本無望,估計考本校分數線能到290。
走校招的話公司一般面試問題方方面面,重點離不開演算法和語言的基礎知識。大廠非常重視校招生的演算法能力,因為校招生專案經驗少,而大廠專案使用者量大。演算法這個就是在力扣上多做題,多瞭解答案思路。
語言基礎知識這塊,就得多看書,有些東西是我們平常開發接觸不到的,面試官又愛問。面試就是這樣,面試造火箭,工作擰螺絲。喜碩學長推薦了兩本書,一本《深入淺出mysql》,翟振興著,一本《深入理解jvm虛擬機器》,周志明著。粗略看了一下《深入淺出mysql》更像是一本mysql的字典,裡面從基本sql語句到sql優化維護都有涉及,心學資料庫沒有教材買本這個書看也可以,肯定比學校發的教材強,學校發的大多都是學校老師自己寫的。並且裡面舉例比較多,好理解。《深入理解jvm虛擬機器》可以當擴充套件讀物看,裡面講了一些java底層一些知識,比如new一個物件具體發生了什麼,jvm如何進行記憶體回收,jvm調優,我們不知道這些東西也不影響我們用java開發。並且舉例較少,建議有一定java基礎和作業系統知識基礎再來看這本書。

mysql鎖概述

鎖是協調各個程式或者執行緒併發訪問一個資源的重要機制。一個好的鎖機制,不僅保證了資料併發訪問的一致性、有效性。並且也儘量減少併發效能的影響。
我們知道InnoDB引擎相對於其他來說支援事務。事務是一組SQL語句組成的邏輯處理單元,具有4個特性,通常簡稱為事務ACID屬性。

  • 原子性:事務是一個原子操作單元,要麼全部執行,要麼全部不執行。
  • 一致性:在事務開始和完成時,資料要保持一致狀態。就是說在事務開始和完成時,資料保持一個正確的狀態。
  • 隔離性:資料庫提供一定的隔離機制,保證事務在不受外部事務影響的環境執行。這意味著事務處理過程中的中間狀態對其他事務來說是不可見的。
  • 永續性:事務完成後,對於資料的修改時永久性的。
    我們拿經典的銀行轉帳來理解事務。
    比如說張三賬戶上想往李四賬戶上轉1000塊錢。
    那麼用sql語句就是這樣的

    update bank set balance = balance - 1000 where name = '張三';
    update bank set balanc = balance + 1000 where name = '李四';

    如果我們將其中的一個欄位打錯,那麼其中一條語句無法正確執行。

    update bank set balance = balance - 1000 where name = '張三';
    update bank set balance = balance + 1000 where name = '李四';

    那麼會照成張三少了1000塊錢而李四沒有多1000塊錢情況。
    如果加入事務則不會發生這種情況。
    原子性保證要麼兩條語句都執行,要麼都不執行。
    一致性保證錢轉帳過程的開始和完成時總數保持不變,且餘額都不會少於0。
    隔離性保證這個事務執行完之前,不會對其他事務造成影響。
    永續性保證事務完成後對錢的修改時永久的。

    併發事務帶來的問題

    併發事務增加了資料庫利用率,提高吞吐量,也帶來了一些問題。

  • 更新丟失:

    事務A事務B
    開啟一個事務開啟一個事務
    將張三賬戶餘額加200將張三賬戶餘額加500
    提交/
    /提交

    這造成了兩個人同時給張三存錢,一個人存200,一個人存500,結果賬戶只多了500,200沒了。

  • 髒讀:

    事務A事務B
    開啟一個事務開啟一個事務
    查詢張三餘額為1000
    如果查詢的結果大於等於1000則將張三賬戶餘額減1000查詢張三餘額為1000
    /如果查詢的結果大於等於1000則將張三賬戶餘額減1000
    /提交
    提交/
  • 不可重複讀:

    事務A事務B
    開啟一個事務開啟一個事務
    查詢張三餘額為1000/
    /將張三賬戶餘額加500
    /提交
    查詢張三餘額為1500/
    提交/

    這造成事務A兩次查詢結果不一致,不知道已哪個為準。

  • 幻讀:

    事務A事務B
    開啟一個事務開啟一個事務
    查詢姓張的人的餘額,查到張三餘額為1000/
    /新建個賬戶叫張四,餘額為0
    /提交
    查詢姓張的人的餘額,查到張三餘額為1000,張四餘額為0/
    提交/

    更新丟失只要保證一個事務在對資料更新提交之前,另一個事務不能更改資料。這個主要靠應用層面來解決。
    髒讀,不可重複讀,幻讀,需要靠資料庫提供的一定的事務隔離機制來解決。資料庫實現資料隔離方式,基本分以下兩種:

  • 一種是在讀取資料前,對其加鎖,阻止其他事務對資料進行更改。
  • 一種是不加任何鎖,通過一定機制生成一個資料請求時間點的資料快照,並用這個快照來提供一定級別的資料讀取。從使用者角度看,好想資料庫可以提供統一資料不同版本,這種技術叫做資料多版本併發控制,也就是MVCC。關於MVCC可以看這篇文章這篇文章
    資料庫事務隔離越嚴格,併發副作用越小,但付出代價越大。這是一個權衡的過程。未來解決隔離與併發矛盾,sql定義了4個事務隔離級別,應用根據自己業務邏輯要求,選擇不同隔離級別來平衡隔離與併發的矛盾。

    髒讀不可重複讀幻讀
    未提交讀 READ-UNCOMMITTED
    已提交讀 READ-COMMITTED
    可重複讀 REPEATABLE-READ
    可序列化 SERIALIZABLE

相關文章