1:for update 的原理
select 檢索出的資料, for update 加上了一把鎖,其他的人是不能修改這個資料的,也不能在給這個資料加鎖,其他執行緒可以檢索出來,但是我在用 for update 再給這些資料加鎖是加不上的,因為這個鎖呢,已經被前一個執行緒給鎖住了,其他人是不能給它加鎖的,在加鎖的期間,其他人也不能修改這些資料,因為update 更新資料呢,是要獲取這些資料的鎖的
2:代碼實作
@Transactional(rollbackFor = Exception.class)
@RequestMapping("/database")
public String databaseLock () throws InterruptedException {
log.info("進入方法");
BusinessLock businessLock = businessLockMapper.getLock("demo");
if (ObjectUtils.isEmpty(businessLock)) {
log.info("分布式鎖找不到");
}
log.info("進入鎖");
Thread.sleep(6000);
log.info("方法執行完成");
return "方法執行完成";
}
mapper 里面的sql
SELECT * FROM business_lock WHERE business_code = #{businessCode} FOR UPDATE
- 開啟兩個實體,埠分別是 8080 8088
- 下圖 8080 應用
- 58:16秒 進入方法
- 58:16秒 進入鎖
- 58:22秒 方法執行完成

- 下圖 8088 應用
- 58:17秒 進入方法
- 58:22秒 進入鎖
- 58:28秒 方法執行完成

在代碼中我們讓獲取到鎖的應用休眠6秒 ,8080 和 8088 差不多同一時間進入方法,
但是8080更早一些所有獲得到了鎖,而8088就在資料庫中阻塞,等待獲取鎖,
在16秒 8080獲得鎖等待6秒 22秒釋放鎖,這時 8088才拿到了鎖,說明在多個應用中鎖是有生效的,
教程原始碼+sql:https://apk-1257934361.cos.ap-guangzhou.myqcloud.com/lock/database-lock/database-lock.zip
3:用native 測for update
- 先將當前頁面的資料庫自動提交先關掉
為什么要先關掉呢?你現在檢索出來以后或者for update 加了鎖,加了鎖以后它馬上事務呢就會自動的去提交,事務提交了,鎖就會自動釋放了,其他的會話,還會檢索出這條資料來
- 下圖:默認是自動提交事務的

- 下圖:這時候都是沒有關閉自動提交事務的,兩者都可以執行加鎖頁面,說明沒有起到我們想要的作用

- 下圖:關閉兩個視窗的自動提交事務

- 再次檢索帶有 for update 關鍵字的sql ,這時候鎖被左視窗鎖住了,導致右視窗無法加鎖,這時候在 左視窗執行commit 提交事務操作,右視窗立馬就查詢出資料了 ,說明鎖是生效的

- 左視窗執行 for update ,右視窗不使用 for update 而是直接執行查詢 是可以查詢出資料的

4:總結

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/148964.html
標籤:其他
上一篇:PHP操作MySQL資料庫
