悲觀鎖和樂觀鎖

2021-10-09 22:21:38 字數 1617 閱讀 9412

1-樂觀鎖:

樂觀鎖並不是真正的鎖,只是更新資料的時候多加一層判斷

例1:

更新的時候判斷此時庫存是否和之前查詢的庫存一樣,

如果一樣則表示沒人修改,可以進行更新;

否則表示有人搶過該資源,不再進行更新

update tb_sku set stock=2 where id=1 and stock=7;

sku.objects.filter(id=1, stock=7).update(stock=2)

例2

也可以在表中加乙個version欄位或者是時間戳字段, 每做一次操作, 對version+1

1. 查出商品資訊

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

2.根據商品資訊生成訂單

3. 修改商品status:

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

只適用於併發較少的情況,如果失敗次數過多,會帶給使用者不良體驗,

同時適用該方法要注意資料庫的隔離級別一定要設定為read committed 。

2-悲觀鎖

行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。這些鎖統稱為悲觀鎖(pessimistic lock)。

悲觀併發控制主要用於資料爭用激烈的環境,

以及發生併發衝突時使用鎖保護資料的成本要低於回滾事務的成本的環境中。

流程:

在對任意記錄進行修改前,先嘗試為該記錄加上排他鎖(exclusive locking)。

如果加鎖失敗,說明該記錄正在被修改,那麼當前查詢可能要等待或者丟擲異常。 具體響應方式由開發者根據實際需要決定。

如果成功加鎖,那麼就可以對記錄做修改,事務完成後就會解鎖了。

其間如果有其他對該記錄做修改或加排他鎖的操作,都會等待我們解鎖或直接丟擲異常。

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

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

悲觀鎖和樂觀鎖

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

悲觀鎖和樂觀鎖

前幾天有人問了我乙個問題,說如果資料庫某些操作不用事務,那麼又需要保持資料的一致性,那麼該用什麼方法替代事務。我就想到了悲觀鎖和樂觀鎖的思想,下面我解釋一下在資料庫中的悲觀鎖和樂觀鎖 1.悲觀鎖就是把資料庫的一些操作,放在事務當中,依賴資料庫的隔離級別,實現對資料修改的封鎖,這樣做資料一致性可以保持...

悲觀鎖和樂觀鎖

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