關係型數據庫(二)

鎖模塊

InnoDB和MyISAM關於鎖方面的區別是什麼

InnoDB默認用的是行級鎖,也支持表級鎖,不使用索引的時候用的是表級鎖。

MyISAM默認用的是表級鎖,不支持行級鎖。

共享鎖(S) 排他鎖(X) 意向共享鎖(IS) 意向排他鎖(IX)
共享鎖(S) 兼容 衝突 兼容 衝突
排他鎖(X)) 衝突 衝突 衝突 衝突
意向共享鎖(IS) 兼容 衝突 兼容 兼容
意向排他鎖(IX) 衝突 衝突 兼容 兼容

InnoDB適用的場景

  • 數據增刪改查都非常頻繁

  • 可靠性要求比較高,要求支持事務

MyISAM適用的場景

  • 頻繁執行全表count語句。MyISAM用一個變量保存了整個表的行數

  • 對數據進行增刪改的頻率不高,查詢非常頻繁。增刪改會有鎖表操作,插入從表的尾部插入,會有很多碎片。

  • 沒有事務的場景

數據庫鎖的分類

  1. 按鎖的粒度劃分,可分爲表級鎖、行級鎖、頁級鎖
  2. 按鎖級別劃分,可分爲共享鎖、排他鎖
  3. 按加鎖方式劃分,可分爲自動鎖、顯式鎖 (for update 、lock in share mode)
  4. 按操作劃分,可分爲DML鎖(數據操作時加的鎖)、DDL鎖(表結構變更加的鎖)
  5. 按使用方式劃分,可分爲樂觀鎖、悲觀鎖

數據庫事務的四大特徵(ACID)

  1. 原子性(Atomic):事務包含的所有操作要麼全部執行,要麼全不執行,失敗回滾

  2. 一致性(Consistency):數據能夠滿足完整性約束,兩個有關聯的數據,一個改變,另一個也隨之改變

  3. 隔離性(Isolation):當多個用戶併發訪問數據 庫時,比如操作同一張表時,數據庫爲每一個用戶開啓的事務,不能被其他事務操作所幹擾,多個併發事務之間要相互隔離

  4. 持久性(Durability):指一個事務一旦被提交了,那麼對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作

事務的隔離級別以及各級別下的併發訪問問題

一、事務併發訪問引起的問題

  1. 更新丟失(Lost Update):兩個事務都同時更新一行數據,但是第二個事務卻中途失敗退出,導致對數據的兩個修改都失效了。這是因爲系統沒有執行任何的鎖操作,因此併發事務並沒有被隔離開來。
  2. 髒讀(Dirty Read):又稱無效數據讀出。一個事務讀取另外一個事務還沒有提交的數據叫髒讀。例如:事務T1修改了一行數據,但是還沒有提交,這時候事務T2讀取了被事務T1修改後的數據,之後事務T1因爲某種原因回滾了,那麼事務T2讀取的數據就是髒的。
  3. 不可重複讀(Non-Repeatable Read):是指在一個事務中兩次讀同一行數據,可是這兩次讀到的數據不一樣。例如:事務T1讀取某一數據,事務T2讀取並修改了該數據,T1爲了對讀取值進行檢驗而再次讀取該數據,便得到了不同的結果。
  4. 幻讀:事務在操作過程中進行兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的數據或者缺少了第一次查詢中出現的數據。
    例如:系統管理員A將數據庫中所有學生的成績從具體分數改爲ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣。

不可重複讀側重於對同一數據的修改,幻讀側重於對數據的新增或刪除。

二、事務的隔離級別

以上的4種問題(更新丟失、髒讀、不可重複讀、幻讀)都和事務的隔離級別有關。通過設置事務的隔離級別,可以避免上述問題的發生。

  1. 讀未提交(Read Uncommitted):讀事務不阻塞其他讀事務和寫事務,未提交的寫事務阻塞其他寫事務但不阻塞讀事務。此隔離級別可以防止更新丟失,但不能防止髒讀、不可重複讀、幻讀。此隔離級別可以通過“排他寫鎖”實現。
  2. 讀已提交(Read Committed):讀事務允許其他讀事務和寫事務,未提交的寫事務禁止其他讀事務和寫事務。此隔離級別可以防止更新丟失、髒讀,但不能防止不可重複讀、幻讀。此隔離級別可以通過“瞬間共享讀鎖”和“排他寫鎖”實現。
  3. 可重複讀取(Repeatable Read):以操作同一行數據爲前提,讀事務禁止其他寫事務但不阻塞讀事務,未提交的寫事務禁止其他讀事務和寫事務。此隔離級別可以防止更新丟失、髒讀、不可重複讀,但不能防止幻讀。此隔離級別可以通過“共享讀鎖”和“排他寫鎖”實現。
  4. 序列化(Serializable):提供嚴格的事務隔離,它要求事務序列化執行,事務只能一個接着一個地執行,不能併發執行。此隔離級別可以防止更新丟失、髒讀、不可重複讀、幻讀。如果僅僅通過“行級鎖”是無法實現事務序列化的,必須通過其他機制保證新插入的數據不會被剛執行查詢操作的事務訪問到。隔離級別越高,越能保證數據的完整性和一致性,但是對併發性能的影響也越大。對於多數應用程序,可以優先考慮把數據庫系統的隔離級別設爲Read Committed。它能夠避免更新丟失、髒讀,而且具有較好的併發性能。儘管它會導致不可重複讀、幻讀這些併發問題,在可能出現這類問題的個別場合,可以由應用程序採用悲觀鎖或樂觀鎖來控制。

當前讀和快照讀

當前讀:加了鎖的增刪改查語句,像select … lock in share mode,select … for update;update,delete,insert;讀取當前記錄的最新版本,並且保證其他併發事務不能修改當前記錄。
在這裏插入圖片描述
快照讀:不加鎖的非阻塞讀,select;在Serializable級別的快照讀也變成爲當前讀;

可重複讀下避免幻讀

next-key鎖(行鎖+gap鎖),gap鎖(間隙鎖)目的是防止同一事務的兩次當前讀出現幻讀的情況。

對主鍵索引或者唯一索引會用gap鎖嗎?

  1. 如果where條件全部命中,不會用gap鎖,只會加記錄鎖;

  2. 如果where條件部分命中或全都不命中,會加gap鎖;

gap鎖出現在非唯一索引或不走索引的當前讀中
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章