資料庫的悲觀鎖和樂觀鎖

2021-10-01 03:01:49 字數 1480 閱讀 2580

悲觀鎖就是對資料的衝突持悲觀態度,也就是假設資料肯定會發生衝突,所以在資料開始讀取的時候就把資料鎖定住。

書籍表book,id為商品id(主鍵),isonline是否上線, 1代表上線,0代表下線,那麼我們如果要對書籍進行下線,就需要將online置為0,假設id為1

如果不採用鎖

1> select * from book where id = 1; //查詢對應的書籍

2> insert into pay_log …;//生成訂單

3> update book set isonline = 0 where id = 1; //做下線處理

採用悲觀鎖

悲觀鎖的原理就是當乙個人將該書籍查詢出來的時候,就將當前的資料鎖定住,等到前乙個人修改完以後,才解鎖,那麼在這個過程中,資料被鎖住了,

其他人也就不能對其進行修改了。

當我們要使用悲觀鎖的時候,必須關閉資料庫的自動提交屬性,因為mysql預設是autocommit自動提交屬性。

set autocommit = 0;

然後就可以執行我們的業務了:

begin;

select * from book where id = 1 for update;

insert into pay_log ......;//生成訂單

update book set isonline = 0 where id = 1; //做下線處理

commit;

與普通查詢不一樣的是使用的是 select…for update,這樣就實現了悲觀鎖。這樣id=1的那條資料就被鎖定住了,等當前事務操作結束後才會解鎖。

這樣就可以保證資料不會被其他事務影響。

補充mysql的innodb預設採用row-level lock,所以只有明確指定(只能是id=1,不能是id>1這樣的形式)主鍵才會執行row lock(只會鎖住對應的資料),則將執行table lock(將整個表單鎖住)。

悲觀鎖也存在著自身的不足,並不適用於任何場景。因為悲觀鎖大多數情況下依靠的是資料庫的鎖機制實現的,以保證操作最大程度的獨占性。如果這個事務很長,那麼加鎖的時間也會很長,其他使用者長時間得不到響應,影響到了系統的併發訪問,同時對資料庫的效能開銷也是很大的。所以和悲觀鎖對應的,有了樂觀

鎖。樂觀鎖認為資料一般情況不會衝突,所以在資料進行提交更新的時候,才會對資料的衝入與否進行檢驗,如果發現衝突了,則返回使用者錯誤的資訊,讓使用者決定如何做。

悲觀鎖的實現大多數基於版本或者時間戳實現:當讀取資料的時候,將version欄位一併取出,資料每更新一次,就將version + 1。當我們提交更新的時候,斷當前版本資訊是否與第一次取出來的版本值相等,如果相等,則更新,否則認為是過期資料,拒絕更新,讓使用者重新操作。

當同時讀取id=1的兩條資料時,兩條資料中的version都是1,當將其中的一條資料進行更新後,version變為2,等另外一條資料進行更新的時候,因為version1,而資料庫中的version為2,更新的時候就會找不到對應的那條資料,更新失敗。類似於svn的原理。

資料庫的悲觀鎖和樂觀鎖

資料庫的四種隔離級別 髒讀 不可重複讀 可重複讀 序列化,雖然四種隔離級別能夠處理事務問題,但是不夠靈活,於是有了悲觀鎖和樂觀鎖。悲觀鎖 對於外界的修改持保守態度,在整個資料處理中資料處於鎖定狀態。以mysql為例,select for update和lock in share model能夠實現悲...

資料庫悲觀鎖和樂觀鎖簡述

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

資料悲觀鎖和樂觀鎖

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