1. 程式人生 > >死鎖,更新鎖,共享鎖,排它鎖,意向鎖,樂觀鎖,悲觀鎖等名詞解釋及案例詳解

死鎖,更新鎖,共享鎖,排它鎖,意向鎖,樂觀鎖,悲觀鎖等名詞解釋及案例詳解

開發過程中一直聽別人說死鎖,可有不理解,今天看了一篇博文講解的非常詳細,簡單易懂,所以,轉載下來。

這裡做個簡明解釋,為下面描述方便,這裡用T1代表一個數據庫執行請求,T2代表另一個請求,也可以理解為T1為一個執行緒,T2 為另一個執行緒。T3,T4以此類推

幾個名詞:

(1)髒讀:當一個事務讀取其它完成一半事務的記錄時,就會發生髒讀取。例如:使用者A,B看到的值都是6,使用者B把值改為2,使用者A讀到的值仍為6。

(2)丟失更新:一個事務的更新覆蓋了其它事務的更新結果,就是所謂的更新丟失。例如:使用者A把值從6改為2,使用者B把值從2改為6,則使用者A丟失了他的更新。

1.死鎖,

原因:多數情況下,可以認為如果一個資源被鎖定,它總會在以後某個時間被釋放。而死鎖發生在當多個程序訪問同一資料庫時,其中每個程序擁有的鎖都是其他程序所需的,由此造成每個程序都無法繼續下去。簡單的說,程序A等待程序B釋放他的資源,B又等待A釋放他的資源,這樣就互相等待就形成死鎖。

形成死鎖的必要條件:

1)互斥條件:指程序對所分配到的資源進行排它性使用,即在一段時間內某資源只由一個程序佔用。如果此時還有其它程序請求資源,則請求者只能等待,直至佔有資源的程序用畢釋放。2)請求和保持條件:指程序已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它程序佔有,此時請求程序阻塞,但又對自己已獲得的其它資源保持不放。3)不剝奪條件:指程序已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。4)環路等待條件:指在發生死鎖時,必然存在一個程序——資源的環形鏈,即程序集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1佔用的資源;P1正在等待P2佔用的資源,……,Pn正在等待已被P0佔用的資源。很明顯從條件四中,可以看出,死鎖也就是死迴圈,兩個程序訪問的資源相互等待,導致誰也達不到目的。

死鎖是一種現象,而下面幾種鎖是我們定義的鎖類別:

2,共享鎖(Shared lock)

  1. 例1:  
  2. ----------------------------------------  
  3. T1:    select * from table (請想象它需要執行1個小時之久,後面的sql語句請都這麼想象)  
  4. T2:    update table set column1='hello'
  5. 過程:  
  6. T1執行 (加共享鎖)  
  7. T2執行  
  8. If T1 還沒執行完  
  9.     T2等......  
  10. else  
  11.     鎖被釋放  
  12.     T2執行  
  13. endif  
  14. T2之所以要等,是因為T2在執行update前,試圖對table表加一個排他鎖,  
  15. 而資料庫規定同一資源上不能同時共存共享鎖和排他鎖。所以T2必須等T1  
  16. 執行完,釋放了共享鎖,才能加上排他鎖,然後才能開始執行update語句。  
  17. 例2:  
  18. ----------------------------------------  
  19. T1:    select * from table  
  20. T2:    select * from table  
  21. 這裡T2不用等待T1執行完,而是可以馬上執行。  
  22. 分析:  
  23. T1執行,則table被加鎖,比如叫lockA  
  24. T2執行,再對table加一個共享鎖,比如叫lockB。  
  25. 兩個鎖是可以同時存在於同一資源上的(比如同一個表上)。這被稱為共  
  26. 享鎖與共享鎖相容。這意味著共享鎖不阻止其它session同時讀資源,但阻  
  27. 止其它session update  
  28. 例3:  
  29. ----------------------------------------  
  30. T1:    select * from table  
  31. T2:    select * from table  
  32. T3:    update table set column1='hello'
  33. 這次,T2不用等T1執行完就能執行,T3卻要等T1和T2都執行完才能執行。  
  34. 因為T3必須等T1和T2的共享鎖全部釋放才能進行加排他鎖然後執行update  
  35. 操作。  
  36. 例4:(死鎖的發生)  
  37. ----------------------------------------  
  38. T1:  
  39. begin tran  
  40. select * from table (holdlock) (holdlock意思是加共享鎖,直到事物結束才釋放)  
  41. update table set column1='hello'
  42. T2:  
  43. begin tran  
  44. select * from table(holdlock)  
  45. update table set column1='world'
  46. 假設T1和T2同時達到select,T1對table加共享鎖,T2也對加共享鎖,當  
  47. T1的select執行完,準備執行update時,根據鎖機制,T1的共享鎖需要升  
  48. 級到排他鎖才能執行接下來的update.在升級排他鎖前,必須等table上的  
  49. 其它共享鎖釋放,但因為holdlock這樣的共享鎖只有等事務結束後才釋放,  
  50. 所以因為T2的共享鎖不釋放而導致T1等(等T2釋放共享鎖,自己好升級成排  
  51. 他鎖),同理,也因為T1的共享鎖不釋放而導致T2等。死鎖產生了。  
  52. 例5:  
  53. ----------------------------------------  
  54. T1:  
  55. begin tran  
  56. update table set column1='hello' where id=10
  57. T2:  
  58. begin tran  
  59. update table set column1='world' where id=20
  60. 這種語句雖然最為常見,很多人覺得它有機會產生死鎖,但實際上要看情  
  61. 況,如果id是主鍵上面有索引,那麼T1會一下子找到該條記錄(id=10的記  
  62. 錄),然後對該條記錄加排他鎖,T2,同樣,一下子通過索引定位到記錄,  
  63. 然後對id=20的記錄加排他鎖,這樣T1和T2各更新各的,互不影響。T2也不  
  64. 需要等。  
  65. 但如果id是普通的一列,沒有索引。那麼當T1對id=10這一行加排他鎖後,  
  66. T2為了找到id=20,需要對全表掃描,那麼就會預先對錶加上共享鎖或更新  
  67. 鎖或排他鎖(依賴於資料庫執行策略和方式,比如第一次執行和第二次執行  
  68. 資料庫執行策略就會不同)。但因為T1已經為一條記錄加了排他鎖,導致  
  69. T2的全表掃描進行不下去,就導致T2等待。  
  70. 死鎖怎麼解決呢?一種辦法是,如下:  
  71. 例6:  
  72. ----------------------------------------  
  73. T1:  
  74. begin tran  
  75. select * from table(xlock) (xlock意思是直接對錶加排他鎖)  
  76. update table set column1='hello'
  77. T2:  
  78. begin tran  
  79. select * from table(xlock)  
  80. update table set column1='world'
  81. 這樣,當T1的select 執行時,直接對錶加上了排他鎖,T2在執行select時,就需要等T1事物完全執行完才能執行。排除了死鎖發生。  
  82. 但當第三個user過來想執行一個查詢語句時,也因為排他鎖的存在而不得不等待,第四個、第五個user也會因此而等待。在大併發  
  83. 情況下,讓大家等待顯得效能就太友好了,所以,這裡引入了更新鎖。  
3,更新鎖(Update lock)
  1. 為解決死鎖,引入更新鎖。  
  2. 例7:  
  3. ----------------------------------------  
  4. T1:  
  5. begin tran  
  6. select * from table(updlock) (加更新鎖)  
  7. update table set column1='hello'
  8. T2:  
  9. begin tran  
  10. select * from table(updlock)  
  11. update table set column1='world'
  12. 更新鎖的意思是:“我現在只想讀,你們別人也可以讀,但我將來可能會做更新操作,我已經獲取了從共享鎖(用來讀)到排他鎖  
  13. (用來更新)的資格”。一個事物只能有一個更新鎖獲此資格。  
  14. T1執行select,加更新鎖。  
  15. T2執行,準備加更新鎖,但發現已經有一個更新鎖在那兒了,只好等。  
  16. 當後來有user3、user4...需要查詢table表中的資料時,並不會因為T1的select在執行就被阻塞,照樣能查詢,相比起例6,這提高  
  17. 了效率。  
  18. 例8:  
  19. ----------------------------------------  
  20. T1:    select * from table(updlock)    (加更新鎖)  
  21. T2:    select * from table(updlock)    (等待,直到T1釋放更新鎖,因為同一時間不能在同一資源上有兩個更新鎖)  
  22. T3:    select * from table (加共享鎖,但不用等updlock釋放,就可以讀)  
  23. 這個例子是說明:共享鎖和更新鎖可以同時在同一個資源上。這被稱為共享鎖和更新鎖是相容的。  
  24. 例9:  
  25. ----------------------------------------  
  26. T1:  
  27. begin  
  28. select * from table(updlock)      (加更新鎖)  
  29. update table set column1='hello'  (重點:這裡T1做update時,不需要等T2釋放什麼,而是直接把更新鎖升級為排他鎖,然後執行update)  
  30. T2:  
  31. begin  
  32. select * from table               (T1加的更新鎖不影響T2讀取)  
  33. update table set column1='world'  (T2的update需要等T1的update做完才能執行)  
  34. 我們以這個例子來加深更新鎖的理解,  
  35. 第一種情況:T1先達,T2緊接到達;在這種情況中,T1先對錶加更新鎖,T2對錶加共享鎖,假設T2的select先執行完,準備執行update,  
  36. 發現已有更新鎖存在,T2等。T1執行這時才執行完select,準備執行update,更新鎖升級為排他鎖,然後執行update,執行完成,事務  
  37. 結束,釋放鎖,T2才輪到執行update。  
  38. 第二種情況:T2先達,T1緊接達;在這種情況,T2先對錶加共享鎖,T1達後,T1對錶加更新鎖,假設T2 select先結束,準備  
  39. update,發現已有更新鎖,則等待,後面步驟就跟第一種情況一樣了。  
  40. 這個例子是說明:排他鎖與更新鎖是不相容的,它們不能同時加在同一子資源上。  

4排他鎖(獨佔鎖,Exclusive Locks)
  1. 即其它事務既不能讀,又不能改排他鎖鎖定的資源。  
  2. 例10  
  3. T1:    update table set column1='hello' where id<1000
  4. T2:    update table set 

    相關推薦

    更新共享意向樂觀悲觀名詞解釋案例

    開發過程中一直聽別人說死鎖,可有不理解,今天看了一篇博文講解的非常詳細,簡單易懂,所以,轉載下來。這裡做個簡明解釋,為下面描述方便,這裡用T1代表一個數據庫執行請求,T2代表另一個請求,也可以理解為T1為一個執行緒,T2 為另一個執行緒。T3,T4以此類推幾個名詞:(1)髒讀

    互斥量概念用法演示解決

    保護共享資料,用程式碼把共享資料鎖住,其他想操作共享資料的執行緒得等待解鎖。 互斥量的概念: 互斥量是個類物件。多個執行緒嘗試lock鎖上。結果:只有一個執行緒能夠鎖定成功,成功的標誌是lock函式返回。如果沒鎖成功,那麼流程就會卡在lock這,不斷嘗試去鎖,一直到成功。 互斥量使用起來要小

    MySQL基礎篇(06):事務管理機制案例

    本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/mysql-data-base) || [GitEE·點這裡](https://github.com/cicadasmile/mysql-data-base) # 一、鎖概念簡介 ## 1、基礎描述 鎖

    “小筆記系列”之《演算法導論》----最近一次修改於2019/1/9更新到第六章。文章主要記錄我看這本書的感受我每看完一章就在這篇文章的基礎上修改一下。

    本人大四上即將結束,於2018年12月18日購《演算法導論》這本書,慢慢看,第一階段先主要理解各個章節說的演算法都是什麼意思,書上的課後習題先不做,用得上什麼演算法我再詳細學習。這是官方課後答案的連結。  放在開頭:沒有好的演算法,壞的演算法之說,重點是針對不同的

    Tomcat 端口配置原理

    request對象 dir 創建 分享圖片 編譯 sel tor 客戶 ces Tomcat 端口配置,及原理詳解 作者:Ezitai 如果想深入了解tomcat的各個端口及

    身份證號碼的正則表達式驗證(JavaScriptRegex)

    新疆 選擇 ade 理學 澳門 如果 span card div 簡言 在做用戶實名驗證時,常會用到身份證號碼的正則表達式及校驗方案。本文列舉了兩種驗證方案,大家可以根據自己的項目實際情況,選擇適合的方案。 身份證號碼說明 居民身份證號碼,正確、正式的稱謂應該是“公民身份

    Python全棧必學知識:如何使用dict和set操作方法正確的案例

    Python內建了字典:dict的支援,dict全稱dictionary,在其他語言中也稱為map,使用鍵-值(key-value)儲存,具有極快的查詢速度。 舉個例子,假設要根據同學的名字查詢對應的成績,如果用list實現,需要兩個list: names = ['Michael', 'Bob

    nohup和&後臺執行程序檢視終止

     nohup 和重定向 功能一樣,可用於定時啟動 1.nohup 用途:不掛斷地執行命令。 語法:nohup Command [ Arg … ] [ & ]   無論是否將 nohup 命令的輸出重定向到終端,輸出都將附加到當前目錄的 n

    nohup和&後臺運行進程查看終止

    padding https ava logs awk nod 占用 定時 htm nohup 和重定向 功能一樣,可用於定時啟動 1.nohup 用途:不掛斷地運行命令。 語法:nohup Command [ Arg … ] [ & ]   無論是否將 noh

    Linux使用者組管理命令整理例項

    使用者,組 相關檔案: /etc/passwd 使用者相關資訊 /etc/login.defs 設定使用者建立時預設相關資訊 /etc/defualt/useradd 使用者新增時會建立的相關資訊設定 /etc/skel

    Python的sys模組如何操作使用正確的案例

    Python本身就內建了很多非常有用的模組,只要安裝完畢,這些模組就可以立刻使用。 我們以內建的sys模組為例,編寫一個hello的模組: #!/usr/bin/env python3 -- coding: utf-8 -- ’ a test module ’

    spring boot介紹使用帶你走進spring

    Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Boot致力於在蓬勃發展的快速應用開發領域(rapid appli

    OpenVPN安裝、配置使用證書驗證、使用者密碼驗證、手機連線配置。

    搞了一天安裝過程中不是很順利,部分文章說明的不是太詳細,因此結合多個文章撰寫的此文,希望能幫上使用OpenVpn的兄弟們。一、OpenVPN     OpenVPN是一個用於建立虛擬專用網路(Virtual Private Network)加密通道的免費開源軟體。使用Op

    Linux如何檢視系統當前登入使用者資訊linux su命令引數用法(linux切換使用者命令)

    作為系統管理員,你可能經常會(在某個時候)需要檢視系統中有哪些使用者正在活動。有些時候,你甚至需要知道他(她)們正在做什麼。本文為我們總結了4種檢視系統使用者資訊(通過編號(ID))的方法。 1. 使用w命令檢視登入使用者正在使用的程序資訊 w命令用於顯示已經登入系統的使用

    入門Python爬蟲爬蟲原理過程

    “入門”是良好的動機,但是可能作用緩慢。如果你手裡或者腦子裡有一個專案,那麼實踐起來你會被目標驅動,而不會像學習模組一樣慢慢學習。

    SpringBoot2 整合Nacos元件環境搭建和入門案例

    本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、Nacos基礎簡介 1、概念簡介 Nacos 是構建以“服務”為中心的現代應用架構,如微服務正規化、雲原生正規化等服務基礎設施。聚焦於發現、配置和管理微服務。Nacos提供一組簡單易用的特性集,幫助開發者快速實現動態服務發現、服務配置、服務元資料

    MySQL/InnoDB中樂觀悲觀共享、行、表概念的理解

    MySQL/InnoDB的加鎖,一直是一個面試中常問的話題。例如,資料庫如果有高併發請求,如何保證資料完整性?產生死鎖問題如何排查並解決?我在工作過程中,也會經常用到,樂觀鎖,排它鎖,等。於是今天就對這幾個概念進行學習,屢屢思路,記錄一下。 注:MySQL是一

    mysql/innoDB中樂觀悲觀共享排他概念的理解

    MySQL是一個支援外掛式儲存引擎的資料庫系統。本文下面的所有介紹,都是基於InnoDB儲存引擎,其他引擎的表現,會有較大的區別。 儲存引擎檢視 MySQL給開發者提供了查詢儲存引擎的功能,我這裡使用的是MySQL5.5.28,可以使用: show engine

    【轉】【MySQL】MySQL中的(表、行共享間隙

    https://blog.csdn.net/soonfly/article/details/70238902 本文參考:  http://mysqlpub.com/thread-5383-1-1.html  http://blog.csdn.net/c466254931/ar

    sql server行級共享的使用

    鎖的概述 一. 為什麼要引入鎖 多個使用者同時對資料庫的併發操作時會帶來以下資料不一致的問題: 丟失更新 A,B兩個使用者讀同一資料並進行修改,其中一個使用者的修改結果破壞了另一個修改的結果,比如訂票系統 髒讀 A使用者修改了資料,隨後B使用者又讀出該資料,但A使用者因為某些原因取消了對資