悲觀鎖,樂觀鎖

2021-09-12 04:05:47 字數 1461 閱讀 1841

面試中被問到了,查詢資料整理下。

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

以常用的mysql innodb儲存引擎為例:加入商品表items表中有乙個欄位status,status=1表示該商品未被下單,status=2表示該商品已經被下單,那麼我們對每個商品下單前必須確保此商品的status=1。假設有一件商品,其id為10000;如果不使用鎖,那麼操作方法如下:

//查出商品狀態

select status from items where id=10000;

//根據商品資訊生成訂單

insert into orders(id,item_id) values(null,10000);

//修改商品狀態為2

update items set status=2 where id=10000;

上述場景在高併發環境下可能出現問題:

前面已經提到只有商品的status=1是才能對它進行下單操作,上面第一步操作中,查詢出來的商品status為1。但是當我們執行第三步update操作的時候,有可能出現其他人先一步對商品下單把item的status修改為2了,但是我們並不知道資料已經被修改了,這樣就可能造成同乙個商品被下單2次,使得資料不一致。所以說這種方式是不安全的。

使用悲觀鎖來實現:在上面的場景中,商品資訊從查詢出來到修改,中間有乙個處理訂單的過程,使用悲觀鎖的原理就是,當我們在查詢出items資訊後就把當前的資料鎖定,直到我們修改完畢後再解鎖。那麼在這個過程中,因為items被鎖定了,就不會出現有第三者來對其進行修改了。

樂觀鎖(optimistic lock), 顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,像資料庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。

以mysql innodb儲存引擎為例,還是拿之前的例子商品表items表中有乙個欄位status,status=1表示該商品未被下單,status=2表示該商品已經被下單,那麼我們對每個商品下單前必須確保此商品的status=1。假設有一件商品,其id為10000;

下單操作包括3步驟:

//查詢出商品資訊

select (status,version) from items where id=#

//根據商品資訊生成訂單

//修改商品status為2

update items set status=2,version=version+1 where id=# and version=#;

為了使用樂觀鎖,我們需要首先修改items表,增加乙個version欄位,資料預設version可設為1;

悲觀鎖樂觀鎖

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

樂觀鎖 悲觀鎖

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

樂觀鎖 悲觀鎖

樂觀鎖 悲觀鎖 悲觀鎖 pessimistic locking 悲觀鎖,正如其名,它指的是對資料被外界 包括本系統當前的其他事務,以及來自外部系統的事務處理 修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制 也只有資料庫層提供的鎖機制才能真正保...