Mysql鎖機制之 樂觀鎖和悲觀鎖

2021-10-09 11:03:36 字數 1475 閱讀 4724

悲觀鎖(pessimistic lock),顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。

注:要使用悲觀鎖,我們必須關閉mysql資料庫的自動提交屬性,因為mysql預設使用autocommit模式,也就是說,當你執行乙個更新操作後,mysql會立刻將結果進行提交。我們可以使用命令設定mysql為非autocommit模式:

set autocommit=0;

設定完autocommit後,我們就可以執行我們的正常業務了。具體如下:

//開始事務

begin;/begin work;/start transaction; (三者選一就可以)

//查詢出商品資訊

select status from items where id=10000 for update;

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

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

//修改商品status為2

update items set status=2 where id=10000;

//提交事務

commit;/commit work;

注:上面的begin/commit為事務的開始和結束,因為在前一步我們關閉了mysql的autocommit,所以需要手動控制事務的提交,在這裡就不細表了。

樂觀鎖定的第二種實現方式和第一種差不多,同樣是在需要樂觀鎖控制的table中增加乙個字段,名稱無所謂,字段型別使用時間戳(timestamp), 和上面的version類似,也是在更新提交的時候檢查當前資料庫中資料的時間戳和自己更新前取到的時間戳進行對比,如果一致則ok,否則就是版本衝突。

以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;

其實我們周圍的很多產品都有樂觀鎖的使用,比如我們經常使用的分布式儲存引擎***,***中儲存的每個資料都有版本號,版本號在每次更新後都會遞增,相應的,在*** put介面中也有此version引數,這個引數是為了解決併發更新同乙個資料而設定的,這其實就是樂觀鎖;

悲觀鎖 面試必備之 樂觀鎖與悲觀鎖

一 什麼是悲觀鎖?什麼是樂觀鎖?1 鎖 lock 在介紹樂觀鎖和悲觀鎖之前,我們先介紹下鎖。在日常生活中,我們經常接觸到鎖這個東西,比如家裡門上的鎖,自行車上的鎖,保險櫃上的鎖等,這些都是為了保障我們的財產安全而上的鎖。而在程式中,鎖是一種保障資料安全的機制和手段。在多併發的情況,當同時多個請求修改...

資料庫之樂觀鎖,悲觀鎖

樂觀鎖 1.只在提交操作時檢查是否違反資料完整性。使用自增長的整數表示資料版本號。更新時檢查版本號是否一致,比如資料庫中資料版本為6,更新提交時version 6 1,使用該version值 7 與資料庫version 1 7 作比較,如果相等,則可以更新,如果不等則有可能其他程式已更新該記錄,所以...

MySQL 樂觀鎖和悲觀鎖

共享鎖 s鎖 又稱讀鎖,若事務t對資料物件a加上s鎖,則事務t可以讀a但不能修改a,其他事務只能再對a加s鎖,而不能加x鎖,直到t釋放a上的s鎖。這保證了其他事務可以讀a,但在t釋放a上的s鎖之前不能對a做任何修改。排他鎖 x鎖 又稱寫鎖。若事務t對資料物件a加上x鎖,事務t可以讀a也可以修改a,其...