關於共享鎖,排它鎖,樂觀鎖,悲觀鎖

轉自:http://blog.csdn.net/yuwei19840916/article/details/3245107mysql

共享鎖【S鎖】
又稱讀鎖,若事務T對數據對象A加上S鎖,則事務T能夠讀A但不能修改A,其餘事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其餘事務能夠讀A,但在T釋放A上的S鎖以前不能對A作任何修改。sql

排他鎖【X鎖】
又稱寫鎖。若事務T對數據對象A加上X鎖,事務T能夠讀A也能夠修改A,其餘事務不能再對A加任何鎖,直到T釋放A上的鎖。這保證了其餘事務在T釋放A上的鎖以前不能再讀取和修改A。數據庫

悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關係型數據庫裏邊就用到了不少這種鎖機制,好比行鎖,表鎖等,讀鎖,寫鎖等,都是在作操做以前先上鎖。安全

 

樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣能夠提升吞吐量,像數據庫若是提供相似於write_condition機制的其實都是提供的樂觀鎖。併發

 

兩種鎖各有優缺點,不可認爲一種好於另外一種,像樂觀鎖適用於寫比較少的狀況下,即衝突真的不多發生的時候,這樣能夠省去了鎖的開銷,加大了系統的整個吞吐量。但若是常常產生衝突,上層應用會不斷的進行retry,這樣反卻是下降了性能,因此這種狀況下用悲觀鎖就比較合適。性能

深刻理解樂觀鎖和悲觀鎖:spa

在數據庫的鎖機制中介紹過,數據庫管理系統(DBMS)中的併發控制的任務是確保在多個事務同時存取數據庫中同一數據時不破壞事務的隔離性和統一性以及數據庫的統一性。.net

樂觀併發控制(樂觀鎖)和悲觀併發控制(悲觀鎖)是併發控制主要採用的技術手段。hibernate

不管是悲觀鎖仍是樂觀鎖,都是人們定義出來的概念,能夠認爲是一種思想。其實不只僅是數據庫系統中有樂觀鎖和悲觀鎖的概念,像memcache、hibernate、tair等都有相似的概念。對象

針對於不一樣的業務場景,應該選用不一樣的併發控制方式。因此,不要把樂觀併發控制和悲觀併發控制狹義的理解爲DBMS中的概念,更不要把他們和數據中提供的鎖機制(行鎖、表鎖、排他鎖、共享鎖)混爲一談。其實,在DBMS中,悲觀鎖正是利用數據庫自己提供的鎖機制來實現的。

悲觀鎖:

在關係數據庫管理系統裏,悲觀併發控制(又名「悲觀鎖」,Pessimistic Concurrency Control,縮寫「PCC」)是一種併發控制的方法。它能夠阻止一個事務以影響其餘用戶的方式來修改數據。若是一個事務執行的操做都某行數據應用了鎖,那只有當這個事務把鎖釋放,其餘事務纔可以執行與該鎖衝突的操做。悲觀併發控制主要用於數據爭用激烈的環境,以及發生併發衝突時使用鎖保護數據的成本要低於回滾事務的成本的環境中。

悲觀鎖,正如其名,它指的是對數據被外界(包括本系統當前的其餘事務,以及來自外部系統的事務處理)修改持保守態度(悲觀),所以,在整個數據處理過程當中,將數據處於鎖定狀態。 悲觀鎖的實現,每每依靠數據庫提供的鎖機制 (也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,不然,即便在本系統中實現了加鎖機制,也沒法保證外部系統不會修改數據)

悲觀鎖的流程:

在對任意記錄進行修改前,先嚐試爲該記錄加上排他鎖(exclusive locking)。

若是加鎖失敗,說明該記錄正在被修改,那麼當前查詢可能要等待或者拋出異常。 具體響應方式由開發者根據實際須要決定。

若是成功加鎖,那麼就能夠對記錄作修改,事務完成後就會解鎖了。

其間若是有其餘對該記錄作修改或加排他鎖的操做,都會等待咱們解鎖或直接拋出異常。

悲觀鎖的優點與不足:

悲觀併發控制其實是「先取鎖再訪問」的保守策略,爲數據處理的安全提供了保證。可是在效率方面,處理加鎖的機制會讓數據庫產生額外的開銷,還有增長產生死鎖的機會;另外,在只讀型事務處理中因爲不會產生衝突,也不必使用鎖,這樣作只能增長系統負載;還有會下降了並行性,一個事務若是鎖定了某行數據,其餘事務就必須等待該事務處理完才能夠處理那行數

樂觀鎖:

在關係數據庫管理系統裏,樂觀併發控制(又名「樂觀鎖」,Optimistic Concurrency Control,縮寫「OCC」)是一種併發控制的方法。它假設多用戶併發的事務在處理時不會彼此互相影響,各事務可以在不產生鎖的狀況下處理各自影響的那部分數據。在提交數據更新以前,每一個事務會先檢查在該事務讀取數據後,有沒有其餘事務又修改了該數據。若是其餘事務有更新的話,正在提交的事務會進行回滾。樂觀事務控制最先是由孔祥重(H.T.Kung)教授提出。

樂觀鎖( Optimistic Locking ) 相對悲觀鎖而言,樂觀鎖假設認爲數據通常狀況下不會形成衝突,因此在數據進行提交更新的時候,纔會正式對數據的衝突與否進行檢測,若是發現衝突了,則讓返回用戶錯誤的信息,讓用戶決定如何去作。

相對於悲觀鎖,在對數據庫進行處理的時候,樂觀鎖並不會使用數據庫提供的鎖機制。通常的實現樂觀鎖的方式就是記錄數據版本。

數據版本,爲數據增長的一個版本標識。當讀取數據時,將版本標識的值一同讀出,數據每更新一次,同時對版本標識進行更新。當咱們提交更新的時候,判斷數據庫表對應記錄的當前版本信息與第一次取出來的版本標識進行比對,若是數據庫表當前版本號與第一次取出來的版本標識值相等,則予以更新,不然認爲是過時數據。

實現數據版本有兩種方式,第一種是使用版本號,第二種是使用時間戳。

樂觀鎖的優點與不足:樂觀併發控制相信事務之間的數據競爭(data race)的機率是比較小的,所以儘量直接作下去,直到提交的時候纔去鎖定,因此不會產生任何鎖和死鎖。但若是直接簡單這麼作,仍是有可能會遇到不可預期的結果,例如兩個事務都讀取了數據庫的某一行,通過修改之後寫回數據庫,這時就遇到了問題。

相關文章
相關標籤/搜索