天天看點

資料庫必知詞彙:資料庫鎖

鎖是資料庫中的一個非常重要的概念,當多個使用者同時對資料庫并發操作時,會帶來資料不一緻的問題,是以,鎖主要用于多使用者環境下保證資料庫完整性和一緻性。

按照不同的方式可以得到不同的資料庫鎖的分類,按照鎖的模式劃分,可分為悲觀鎖、樂觀鎖;按照鎖的範圍劃分,可以分為表鎖、行鎖;按照鎖的算法劃分,可分為臨鍵鎖、間隙鎖、記錄鎖等;按照鎖的屬性劃分,可以分為共享鎖、排他鎖等;按照鎖的狀态劃分,可以分為意向共享鎖、意向排他鎖等。

這裡對于幾種經常出現的鎖進行介紹:

悲觀鎖(Pessimistic Lock):正如其名,具有強烈的獨占和排他特性。它指的是對資料被外界(包括本系統目前的其他事務,以及來自外部系統的事務處理)修改持保守态度,是以,在整個資料處理過程中,将資料處于鎖定狀态。悲觀鎖的實作,往往依靠資料庫提供的鎖機制(也隻有資料庫層提供的鎖機制才能真正保證資料通路的排他性,否則,即使在本系統中實作了加鎖機制,也無法保證外部系統不會修改資料)。

樂觀鎖( Optimistic Locking ):相對悲觀鎖而言,樂觀鎖機制采取了更加寬松的加鎖機制。悲觀鎖大多數情況下依靠資料庫的鎖機制實作,以保證操作最大程度的獨占性。但随之而來的就是資料庫性能的大量開銷,特别是對長事務而言,這樣的開銷往往無法承受。而樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基于資料版本( Version )記錄機制實作。這裡的資料版本的含義:為資料增加一個版本辨別,在基于資料庫表的版本解決方案中,一般是通過為資料庫表增加一個 “version” 字段來實作。讀取出資料時,将此版本号一同讀出,之後更新時,對此版本号加一。此時,将送出資料的版本資料與資料庫表對應記錄的目前版本資訊進行比對,如果送出的資料版本号大于資料庫表目前版本号,則予以更新,否則認為是過期資料。

行鎖:行鎖就是一鎖鎖一行或者多行記錄,MySQL的行鎖是基于索引加載的,是以行鎖是要加在索引響應的行上,即命中索引。行鎖沖突機率低,并發性高,但是會有死鎖的情況出現。

表鎖:表鎖就是一鎖鎖一整張表,在表被鎖定期間,其他事務不能對該表進行操作,必須等目前表的鎖被釋放後才能進行操作。表鎖響應的是非索引字段,即全表掃描,全表掃描時鎖定整張表,SQL語句可以通過執行計劃看出掃描了多少條記錄。由于表鎖每次都是鎖一整張表,是以表鎖的鎖沖突幾率特别高,表鎖不會出現死鎖的情況。

記錄鎖:記錄鎖鎖的是表中的某一條記錄,記錄鎖的出現條件必須是精準命中索引并且索引是唯一索引,如主鍵id。

間隙鎖:又稱之為區間鎖,每次鎖定都是鎖定一個區間,隸屬行鎖。既然間隙鎖隸屬行鎖,那麼,間隙鎖的觸發條件必然是命中索引的,當我們查詢資料用範圍查詢而不是相等條件查詢時,查詢條件命中索引,并且沒有查詢到符合條件的記錄,此時就會将查詢條件中的範圍資料進行鎖定(即使是範圍庫中不存在的資料也會被鎖定)。

臨鍵鎖:MySQL的行鎖預設就是使用的臨鍵鎖,臨鍵鎖是由記錄鎖和間隙鎖共同實作的。間隙鎖的觸發條件是命中索引,範圍查詢沒有比對到相關記錄。而臨鍵鎖恰好相反,臨鍵鎖的觸發條件也是查詢條件命中索引,不過,臨鍵鎖有比對到資料庫記錄。

資料來源:

深入了解資料庫行鎖與表鎖

https://zhuanlan.zhihu.com/p/52678870

資料庫鎖分類和總結

https://blog.csdn.net/weixin_39651041/article/details/79985715

資料庫鎖相關

https://www.cnblogs.com/joeysh/p/10748511.html