資料庫中樂觀鎖和悲觀鎖的詳解

2021-07-23 20:43:32 字數 1905 閱讀 1194

資料中的鎖分為兩類:

悲觀鎖和

樂觀鎖,鎖還有表級鎖、行級鎖

表級鎖例如:

select * from table with (holdlock) 其他事務可以讀取表,但不能更新刪除

select * from table with (tablockx) 其他事務不能讀取表,更新和刪除

行級鎖例如:

select * from table_name where id = 1 for update;

悲觀鎖(pressimistic locking)

對資料被外界(包括本系統當前的其他事務,以及來自

外部系統的

事務處理)修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的

排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系

統不會修改資料)。例如:

select * from table_name where id = 『***』 for update;

這樣查詢出來的這一行資料就被鎖定了,在這個update事務提交之前其他外界是不能修改這條資料的,但是這種處理方式效率比較低,一般不推薦使用。

樂觀鎖(optimistic locking)

相對悲觀鎖而言,樂觀鎖機制採取了更加寬鬆的加鎖機制。悲觀鎖大多數情況下依靠資料庫的鎖機制實現,以保證操作最大程度的獨占性。但隨之而來的就是資料庫效能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。如乙個金融系統,當某個操作員讀取使用者的資料,並在讀出的使用者資料的基礎上進行修改時(如更改使用者帳戶餘額),如果採用悲觀鎖機制,也就意味著整個操作過程中(從操作員讀出資料、開始修改直至提交修改結果的全過程,甚至還包括操作員中途去煮咖啡的時間),資料庫記錄始終處於加鎖狀態,可以想見,如果面對幾百上千個併發,這樣的情況將導致怎樣的後果。

樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基於資料版本( version )記錄機制實現。何謂資料版本?即為資料增加乙個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表增加乙個 「version」 欄位來實現。讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交資料的版本資料與資料庫表對應記錄的當前版本資訊進行比對,如果提交的資料版本號大於資料庫表當前版本號,則予以更新,否則認為是過期資料。

舉個樂觀鎖的例子(資料庫version預設為0):

不如現在一件衣服就剩乙個庫存了,但是有兩個使用者同時下單,如果這時候不加以控制很容易出現庫存賣超的情況,這時候我們可以這樣操作:

第乙個使用者將這件衣服讀出(version=0),並將庫存-1,

第二個使用者也將這件衣服讀出(version=0),並將庫存-1,

第乙個個使用者完成操作,將資料庫版本version+1,執行更新庫存時由於提交的資料版本大於資料庫記錄的版本,資料被更新,資料庫中的version被更新為2。

update goods set store=store-1,version=version+1 where id=xx and version=orginal_version

第二個使用者也完成了操作,也將版本version+1,執行更新庫存時發現執行版本和資料庫記錄的版本相同,不符合提交版本必須大於資料庫記錄版本的樂觀鎖策略,所以第二個使用者的下單請求被駁回,我們可以通過人性化處理異常給使用者提示該商品已售罄等。

樂觀鎖機制避免了長事務中的資料庫加鎖開銷(兩個使用者操作過程中,都沒有對資料庫資料加鎖),大大提公升了大併發量下的系統整體效能表現。

悲觀鎖:交給資料庫來處理的,由事務(分隱私和

顯式事務,平時單條sql語句就是乙個隱式事務)+鎖 那控制的,其中事務相當於鎖的作用域,根據事務的提交失敗或回滾來釋放掉顯式事務中開啟的鎖。(事前處理)

樂觀鎖:是認為版本號來控制的,這種機制

併發性和效能更好(事後處理)

資料庫中樂觀鎖和悲觀鎖的理解

鎖 locking 業務邏輯的實現過程中,往往需要保證資料訪問的排他性。如在金融系統的日終結算 處理中,我們希望針對某個 cut off 時間點的資料進行處理,而不希望在結算進行過程中 可能是幾秒種,也可能是幾個小時 資料再發生變化。此時,我們就需要通過一些機 制來保證這些資料在某個操作過程中不會被...

資料庫中樂觀鎖與悲觀鎖的概念

資料庫中樂觀鎖與悲觀鎖的概念 今天早上起來,靜靜的看技術部落格,發現了一篇好文章 鎖 locking 業務邏輯的實現過程中,往往需要保證資料訪問的排他性。如在金融系統的日終結算 處理中,我們希望針對某個 cut off 時間點的資料進行處理,而不希望在結算進行過程中 可能是幾秒種,也可能是幾個小時 ...

java中樂觀鎖和悲觀鎖的區別

悲觀鎖 pessimistic lock 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。它指的是對資料被外...