Pessimistic and Optimistic locking

事務隔離通常通過鎖定任何對事務中資源的訪問來實現的。總的來說,有兩種方法針對事務的鎖定:樂觀鎖(Pessimistic locking)和悲觀鎖(Optimistic locking)

悲觀鎖(Pessimistic locking)

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

悲觀鎖的缺點在於,資源第一次的訪問就會被事務鎖定,除非事務完成,資源始終是不可訪問的。如果大量事務都是僅僅對事務進行檢索而不是更新操作,那麼這種排它鎖會大量阻塞,引起鎖的爭用。這種情況下,樂觀鎖會是一種更好的方案。在使用悲觀鎖的情況下,是通過請求失敗來保證併發安全性的。以銀行系統爲例,一旦一個賬戶通過事務來訪問,那麼就會鎖定整個賬戶。其他的事務嘗試訪問賬戶都會被延遲,阻塞,直到之前的事務結束(完成或者回滾)。悲觀鎖會一直存在,直到事務提交或者回滾。

樂觀鎖( Optimistic Locking )

樂觀鎖( Optimistic Locking ) 相對悲觀鎖而言,樂觀鎖假設認爲數據一般情況下不會造成衝突,所以在數據進行提交更新的時候,纔會正式對數據的衝突與否進行檢測,如果發現衝突了,則讓返回用戶錯誤的信息,讓用戶決定如何去做。那麼我們如何實現樂觀鎖呢,一般來說有以下2種方式:

  • 使用數據版本(Version)記錄機制實現,這是樂觀鎖最常用的一種實現方式。何謂數據版本?即爲數據增加一個版本標識,一般是通過爲數據庫表增加一個數字類型的 “version” 字段來實現。當讀取數據時,將version字段的值一同讀出,數據每更新一次,對此version值加一。當我們提交更新的時候,判斷數據庫表對應記錄的當前版本信息與第一次取出來的version值進行比對,如果數據庫表當前版本號與第一次取出來的version值相等,則予以更新,否則認爲是過期數據。
  • 樂觀鎖定的第二種實現方式和第一種差不多,同樣是在需要樂觀鎖控制的table中增加一個字段,名稱無所謂,字段類型使用時間戳(timestamp), 和上面的version類似,也是在更新提交的時候檢查當前數據庫中數據的時間戳和自己更新前取到的時間戳進行對比,如果一致則OK,否則就是版本衝突。

在使用樂觀鎖的時候,資源並不會在第一次由事務訪問的時候就鎖定,相反,資源的狀態會使用悲觀鎖的方式鎖定。當其他事務併發的訪問資源,並且訪問資源的時候,是可能出現衝突的。當提交的時候,資源將要持久化到存儲的時候,會重新讀取資源的狀態,然後對比事務第一次訪問的時候所鎖定的狀態,如果兩個狀態不同,就會有衝突,從而事務會回滾。

同樣以銀行應用爲例,賬戶第一次由事務訪問的時候,就記錄了賬戶的餘額。當事務修改了賬戶的餘額的時候,賬戶的信息會在執行更新之前再次查詢賬戶的餘額。如果餘額在事務期間有變化,那麼事務就會失敗,如果餘額沒有變化,那麼這次修改就會被持久化到存儲中。

樂觀併發控制(Optimistic concurrency control)

樂觀併發控制(OCC)是一種應用到事務系統中的併發控制方法,比如在關係數據庫管理系統以及軟件事務內存等。OCC的理論依據是多數事務在執行更新的時候,是不會影響到彼此的。在運行時,事務使用資源是不需要獲取資源的鎖的,但是在提交之前,每個事務都會驗證並沒有其他的事務在修改數據。如果檢查碰到了更新衝突,那麼事務的提交會回滾,然後重新執行。

前面提到了OCC的理論依據,所以OCC一般用於低數據衝突的環境。當爭用很少的時候,事務就能夠幾乎不需要付出管理鎖的代價,也不需要等待其他事務完成了。這樣可以比其它併發控制帶來更高的吞吐。當然了,如果數據資源頻繁出現爭用的話,那麼事務的重啓就會嚴重的影響性能了。這個時候使用其他併發控制可能更好。然而,基於鎖的方法(悲觀鎖)在鎖定數據的時候,會嚴重限制併發性能。

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