共享鎖、排他鎖、互斥鎖、悲觀鎖、樂觀鎖、行鎖、表鎖、頁面鎖、不可重複讀、丟失修改、讀髒數據

2021-02-15 Java知音

共享鎖(S鎖): 又稱為讀鎖,可以查看但無法修改和刪除的一種數據鎖。如果事務T對數據A加上共享鎖後,則其他事務只能對A再加共享鎖,不能加排它鎖。獲準共享鎖的事務只能讀數據,不能修改數據。 共享鎖下其它用戶可以並發讀取,查詢數據。但不能修改,增加,刪除數據。資源共享.

排它鎖(X鎖): 又稱為寫鎖、獨佔鎖,若事務T對數據對象A加上X鎖,則只允許T讀取和修改A,其他任何事務都不能再對A加任何類型的鎖,直到T釋放A上的鎖。這就保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A

互斥鎖: 在編程中,引入了對象互斥鎖的概念,來保證共享數據操作的完整性。每個對象都對應於一個可稱為" 互斥鎖" 的標記,這個標記用來保證在任一時刻,只能有一個線程訪問該對象。

悲觀鎖、樂觀鎖:

悲觀鎖: 總是假設最壞的情況,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。再比如Java裡面的同步原語synchronized關鍵字的實現也是悲觀鎖。

悲觀鎖和樂觀鎖推薦:面試難點:你了解樂觀鎖和悲觀鎖嗎?

樂觀鎖: 顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像資料庫提供的類似於write_condition機制,其實都是提供的樂觀鎖。在Java中java.util.concurrent.atomic包下面的原子變量類就是使用了樂觀鎖的一種實現方式CAS實現的。

參考:www.cnblogs.com/qjjazry/p/6581568.html

行級鎖: 行級鎖是 MySQL 中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少資料庫操作的衝突,其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖和排他鎖。開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,並發度也最高。

表級鎖: 表級鎖是 MySQL 中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖,它實現簡單,資源消耗較少,被大部分 MySQL 引擎支持。最常使用的 MyISAM 與 InnoDB 都支持表級鎖定。表級鎖定分為表共享讀鎖(共享鎖)與表獨佔寫鎖(排他鎖)。開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發出鎖衝突的概率最高,並發度最低。

頁級鎖: 頁級鎖是 MySQL 中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。因此,採取了折衷的頁級鎖,一次鎖定相鄰的一組記錄。BDB 支持頁級鎖。開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般。

丟失修改: 指事務1和事務2同時讀入相同的數據並進行修改,事務2提交的結果破壞了事務1提交的結果,導致事務1進行的修改丟失。

不可重複讀: 一個事務在讀取某些數據後的某個時間,再次讀取以前讀過的數據,卻發現其讀出的數據已經發生了改變、或某些記錄已經被刪除了!

不可重複讀推薦:面試官:MySQL的可重複讀級別能解決幻讀問題嗎?

讀髒數據: 事務T1修改某一數據,並將其寫回磁碟,事務T2讀取同一數據後,T1由於某種原因被撤消,這時T1已修改過的數據恢復原值,T2讀到的數據就與資料庫中的數據不一致,則T2讀到的數據就為"髒"數據,即不正確的數據。

死鎖: 兩個或兩個以上的進程在執行過程中,由於競爭資源或者由於彼此通信而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的進程稱為死鎖進程

死鎖推薦閱讀:MySQL死鎖產生原因和解決方法

死鎖四個產生條件:

1)互斥條件: 指進程對所分配到的資源進行排它性使用,即在一段時間內某資源只由一個進程佔用。如果此時還有其它進程請求資源,則請求者只能等待,直至佔有資源的進程用畢釋放。

2)請求和保持條件: 指進程已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它進程佔有,此時請求進程阻塞,但又對自己已獲得的其它資源保持不放。

3)不剝奪條件: 指進程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。

4)環路等待條件: 指在發生死鎖時,必然存在一個進程——資源的環形鏈,即進程集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1佔用的資源;P1正在等待P2佔用的資源,……,Pn正在等待已被P0佔用的資源。

預防死鎖打破上述之一的條件。

相關焦點

  • 資料庫常見面試題:樂觀、悲觀鎖,行鎖、表鎖、讀、寫鎖,間隙鎖
    常的場景是全庫邏輯備份(也就是把整庫每個表都select出來存成本),對於InnoDB可以可重複讀這隔離級別進備份,但是對於MyISAM只能全局鎖表級鎖。表鎖: lock tables t1 read, t2 write; 那麼該線程只能讀t1,寫t2,其他線程只能寫t1,讀t2。
  • 面試官:你說說互斥鎖、自旋鎖、讀寫鎖、悲觀鎖、樂觀鎖的應用場景
    接下來,就談一談常見的這幾種鎖:多線程訪問共享資源的時候,避免不了資源競爭而導致數據錯亂的問題,所以我們通常為了解決這一問題,都會在訪問共享資源之前加鎖。最常用的就是互斥鎖,當然還有很多種不同的鎖,比如自旋鎖、讀寫鎖、樂觀鎖等,不同種類的鎖自然適用於不同的場景。
  • Java 中15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖,樂觀鎖,分段鎖,自旋鎖等等
    介紹的內容如下:1.公平鎖 / 非公平鎖2.可重入鎖 / 不可重入鎖3.獨享鎖 / 共享鎖4.互斥鎖 / 讀寫鎖5.樂觀鎖 / 悲觀鎖6.分段鎖7.偏向鎖 / 輕量級鎖 / 重量級鎖8.自旋鎖上面是很多鎖的名詞,這些分類並不是全是指鎖的狀態,有的指鎖的特性,有的指鎖的設計,下面總結的內容是對每個鎖的名詞進行一定的解釋
  • PostgreSQL中的表鎖
    最開始只有兩種鎖:Share與Exclusive,共享鎖與排它鎖,即所謂讀鎖與寫鎖。讀鎖的目的是阻止表數據的變更,而寫鎖的目的是阻止一切並發訪問。這很好理解。因而原有的鎖模型就需要升級了:這裡的共享鎖與排他鎖都有了一個升級版本,即前面多加一個ACCESS。ACCESS SHARE是改良版共享鎖,即允許ACCESS(多版本並發訪問)的SHARE鎖,這種鎖意味著即使其他進程正在並發修改數據也不會阻塞本進程讀取數據。
  • 解決MySQL可重複讀——詳解間隙鎖
    間隙鎖(Gap Lock)是Innodb在可重複讀提交下為了解決幻讀問題時引入的鎖機制,(下面的所有案例沒有特意強調都使用可重複讀隔離級別)幻讀的問題存在是因為新增或者更新操作,這時如果進行範圍查詢的時候(加鎖查詢),會出現不一致的問題,這時使用不同的行鎖已經沒有辦法滿足要求,需要對一定範圍內的數據進行加鎖,間隙鎖就是解決這類問題的。
  • 如何理解互斥鎖、條件變量、讀寫鎖以及自旋鎖?
    其思想簡單粗暴,多線程共享一個互斥量,然後線程之間去競爭。得到鎖的線程可以進入臨界區執行代碼。在讀多寫少的場景下,不加區分的使用互斥量顯然是有點浪費的。此時便該上演讀寫鎖的拿手好戲。讀寫鎖有一個別稱叫『共享-獨佔鎖』。不過單看『共享-獨佔鎖』或者『讀寫鎖』這兩個名稱,其實並未區分對於讀和寫,到底誰共享,誰獨佔。可能會讓人誤以為讀寫鎖是一種更為泛化的稱呼,其實不是。讀寫鎖的含義是準確的:是一種 讀共享,寫獨佔的鎖。
  • MySQL中悲觀鎖和樂觀鎖到底是什麼?
    索引和鎖是資料庫中的兩個核心知識點,隔離級別的實現都是通過鎖來完成的 按照鎖顆粒對鎖進行劃分 ? 鎖用來對數據進行鎖定,我們可以從鎖定對象的粒度大小來對鎖進行劃分,分別為行鎖、頁鎖和表鎖。
  • 原子操作和互斥鎖的區別
    我們使用的mutex互斥鎖類似悲觀鎖,總是假設會有並發的操作要修改被操作的值,所以使用鎖將相關操作放入臨界區中加以保護。而使用CAS操作的做法趨於樂觀鎖,總是假設被操作值未曾被改變(即與舊值相等),並一旦確認這個假設的真實性就立即進行值替換。在被操作值被頻繁變更的情況下,CAS操作並不那麼容易成功所以需要不斷進行嘗試,直到成功為止。
  • MySQL InnoDB 引擎中的 7 種鎖類型,你都知道嗎?
    共享/排它鎖(Shared and Exclusive Locks)使用的語義為:共享鎖之間不互斥,簡記為:讀讀可以並行排他鎖與任何鎖互斥,簡記為:寫讀,寫寫不可以並行可以看到,一旦寫數據的任務沒有完成,數據是不能被其他任務讀取的,這對並發度有較大的影響。
  • 陌陌面試官:談談你對MySQL中事務和鎖的理解?
    不可重複讀(Non-Repeatable Read) 不可重複讀指的是在一個事務執行過程中,讀取到其它事務已提交的數據,導致兩次讀取的結果不一致。不可重複讀和幻讀的區別在於不可重複讀是讀到的是其他事務修改或者刪除的數據,而幻讀讀到的是其它事務新插入的數據。髒寫的問題太嚴重了,任何隔離級別都必須避免。其它無論是髒讀,不可重複讀,還是幻讀,它們都屬於資料庫的讀一致性的問題,都是在一個事務裡面前後兩次讀取出現了不一致的情況。# 四種隔離級別在SQL標準中設立了4種隔離級別,用來解決上面的讀一致性問題。
  • Lock鎖 精講
    鎖是一種用於控制多個線程對共享資源的訪問的工具。通常,鎖提供對共享資源的獨佔訪問,一次只能有一個線程可以獲取該鎖,並且對共享資源的所有訪問都需要首先獲取該鎖。但是,某些鎖可能允許並發訪問共享資源,例如ReadWriteLock的讀取鎖。
  • InnoDB加鎖實驗
    從模式層面分, 鎖主要包括讀鎖(shared lock, 後面簡稱S鎖)和寫鎖(exclusive lock, 後面簡稱X鎖), 這個讀寫的概念, 在行級鎖和表級鎖中都有體現. 與行級鎖對應的還有表級鎖(table lock, 簡單來說就是鎖定整張表, 比如要刪除所有數據), 意向鎖(intension lock, 按讀寫分, 後面簡稱IS, IX).
  • 小夥一步步試探MySQL鎖機制,居然是這樣?
    共享鎖 (Shared Locks)第一個行級別的鎖就是我們在官網看到的 Shared Locks (共享鎖),我們獲取了 一行數據的讀鎖以後,可以用來讀取數據,所以它也叫做讀鎖,多個事務可以共享一把讀鎖。靈魂一問:你知道怎麼給一行數據加上讀鎖嗎?
  • 通過加鎖控制Oracle資料庫並發事務
    鎖可以防止用戶訪問同一數據是相互幹擾,而事務之間存在著不同級別的隔離作用。通過加鎖避免 寫數據丟失在Oracle中,解決兩個寫事務衝突的方法就是採用「加鎖」。如當A事務要修改- - 數據時,就對該數據加鎖,禁止其他事務對該數據的修改。只有當A事務完成寫操作並將鎖打開後,才運行其他事務的寫操作。
  • 資料庫:MySQL 中 「select ... for update」 排他鎖分析
    來源:blog.csdn.net/claram/article/details/54023216Mysql InnoDB 排他鎖場景分析測試環境總結參考資料Mysql InnoDB 排他鎖用法:select … for update;例如
  • Java並發包下Java多線程並發之讀寫鎖鎖學習第五篇-讀寫鎖
    Rlock比起synchronized(下文簡稱Sync)來說有三個優點:RLock可以被中斷;RLock可以有公平鎖;RLock可以綁定多個條件。那麼既然RLock比Sync有這麼多優點,為什麼還需要讀寫鎖呢?那是因為RLock是獨佔式(排他) 鎖,即當線程1獲取到資源的時候,其他線程不能再來操作共享資源了。
  • 史上最全的select加鎖分析(Mysql)
    下面囉嗦點基礎知識鎖類型 共享鎖(S鎖):假設事務T1對數據A加上共享鎖,那麼事務T2可以讀數據A,不能修改數據A。排他鎖(X鎖):假設事務T1對數據A加上共享鎖,那麼事務T2不能讀數據A,不能修改數據A。我們通過update、delete等語句加上的鎖都是行級別的鎖。只有LOCK TABLE … READ和LOCK TABLE … WRITE才能申請表級別的鎖。
  • 史上最全的select加鎖分析(MySQL)
    下面囉嗦點基礎知識鎖類型共享鎖(S鎖):假設事務T1對數據A加上共享鎖,那麼事務T2可以讀數據A,不能修改數據A。排他鎖((X鎖):假設事務T1對數據A加上共享鎖,那麼事務T2不能讀數據A,不能修改數據A。我們通過update、delete等語句加上的鎖都是行級別的鎖。只有LOCK TABLE … READ和LOCK TABLE … WRITE才能申請表級別的鎖。
  • 淺談偏向鎖、輕量級鎖、重量級鎖
    隱藏在內置鎖下的基本問題內置鎖是JVM提供的最便捷的線程同步工具,在代碼塊或方法聲明上添加synchronized關鍵字即可使用內置鎖。使用內置鎖能夠簡化並發模型;隨著JVM的升級,幾乎不需要修改代碼,就可以直接享受JVM在內置鎖上的優化成果。
  • golang下文件鎖的使用
    為什麼需要文件鎖只有多線程/多進程這種並發場景下讀寫文件,才需要加鎖,場景1-讀寫並發讀寫並發場景下,如果不加鎖,就會出現讀到髒數據的情況。想像一下,讀文件的進程,讀到第500位元組,有其它進程以覆蓋寫的方式向文件中寫入1000位元組,那讀進程讀到的後500位元組就是髒數據。