Mysql之樂觀鎖悲觀鎖:樂觀鎖檢查數據狀態 悲觀鎖更新時鎖定數據

1.問題來源

就是一數據表的數據  在兩個人同時修改的時候  會出現混亂 

例子:如一個字段記錄status=1 表示可以下單  貨品只有1個的時候    a下單的同時b也下單 ; a有修改status的機會  b也有修改的機會;但是a下單成功  b下單未知   這就會出現矛盾 與現實的不想符合!

2.悲觀鎖

悲觀鎖是對數據被的修改持悲觀態度(認爲數據在被修改的時候一定會存在併發問題),因此在整個數據處理過程中將數據鎖定。悲觀鎖的實現,往往依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,否則,即使在應用層中實現了加鎖機制,也無法保證外部系統不會修改數據)。

(翻譯:就是悲觀鎖認爲所有的數據表操作都會有併發問題  所以依靠自身的鎖機制來一個鎖定一次處理完好之後 再進行下一次的數據操作)

3.悲觀鎖的方法

在上面的場景中,商品信息從查詢出來到修改,中間有一個處理訂單的過程,使用悲觀鎖的原理就是,當我們在查詢出goods信息後就把當前的數據鎖定,直到我們修改完畢後再解鎖。那麼在這個過程中,因爲goods被鎖定了,就不會出現有第三者來對其進行修改了。要使用悲觀鎖,我們必須關閉mysql數據庫的自動提交屬性。

set autocommit=0;  
//設置完autocommit後,我們就可以執行我們的正常業務了。具體如下:
//0.開始事務
begin;/begin work;/start transaction; (三者選一就可以)
//1.查詢出商品信息
select status from t_goods where id=1 for update;
//2.根據商品信息生成訂單
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status爲2
update t_goods set status=2;
//4.提交事務
commit;/commit work;

使用了select…for update的方式,這樣就通過數據庫實現了悲觀鎖

SELECT ... LOCK IN SHARE MODE 

SELECT ... FOR UPDATE

而主要的不同在於LOCK IN SHARE MODE 在有一方事務要Update 同一個表單時很容易造成死鎖。如果SELECT 後面若要UPDATE 同一個表單,最好使用SELECT ... UPDATE

4.Row Lock與Table Lock

默認Row Lock  只要指定id 就是行鎖  沒有指定就是表鎖

5.鎖定分析

5.1 明確指定主鍵,並且有此數據,row lock

5.2 明確指定主鍵,若查無此數據,無lock

5.3 無主鍵,table lock

5.4 主鍵不明確,table lock

5.5 明確指定索引,並且有此數據,row lock

5.6 明確指定索引,若查無此數據,無lock

6.樂觀鎖

悲觀鎖:在讀取數據時鎖住那幾行,其他對這幾行的更新需要等到悲觀鎖結束時才能繼續 。
樂觀所:讀取數據時不鎖,更新時檢查是否數據已經被更新過(添加where條件即可判斷是否更新了!),如果是則取消當前更新,一般在悲觀鎖的等待時間過長而不能接受時我們纔會選擇樂觀鎖  適用於高併發的情況

 

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