SpringBoot+MyBatisPlus中樂觀鎖的實(shí)現(xiàn)示例
樂觀鎖加注解@Version后不需要手動進(jìn)行加1操作。樂觀鎖是一種用于解決并發(fā)沖突的機(jī)制,在數(shù)據(jù)庫中用于保護(hù)數(shù)據(jù)的一致性。@Version注解是MyBatisPlus框架中的樂觀鎖注解,它會在更新數(shù)據(jù)時自動檢查版本號是否一致,如果一致則進(jìn)行更新操作,如果不一致則表示數(shù)據(jù)已被其他線程修改過,更新操作會失敗。
@Version注解會自動對版本號進(jìn)行加1操作,所以在使用樂觀鎖時不需要手動進(jìn)行加1操作。當(dāng)進(jìn)行更新操作時,MyBatisPlus會自動更新版本號,并將更新后的版本號與更新條件一起發(fā)送給數(shù)據(jù)庫,如果版本號在更新過程中發(fā)生變化,則說明數(shù)據(jù)已被其他線程修改,更新操作會失敗。
因此,使用樂觀鎖加注解@Version后,可以簡化代碼,并且可以保證數(shù)據(jù)的一致性
使用場景: 當(dāng)要更新一條數(shù)據(jù)時,希望這條數(shù)據(jù)沒有被別人更新,也就是說實(shí)現(xiàn)線程安全的數(shù)據(jù)更新
1. 數(shù)據(jù)庫新增version字段, int類型, 默認(rèn)值為0

2. 引入依賴
<!--MyBatisPlus 攔截器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency>
3. springboot啟動類中新增bean
/**
* 支持?jǐn)r截器樂觀鎖
*
* @return
*/
@Bean
public MybatisPlusInterceptor optimisticLockerInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}4. 實(shí)體類 version字段貼上注解 @Version
@Version private Long version;
5. sql更新語句 (@Version注解會自動對版本號進(jìn)行加1操作,所以在使用樂觀鎖時不需要手動進(jìn)行加1操作)
// 沒加@Version注解sql
update wx_dept set name=#{name}, sn=#{sn}, version=#{version}+1 where id=#{id} and version=#{version}
// 加了@Version注解sql
update wx_dept set name=#{name}, sn=#{sn}, version=#{version} where id=#{id} and version=#{version}6. service (樂觀鎖操作步驟: 每次操作前都是先查詢、替換、最后更新, 否則樂觀鎖無效)
/**
* 修改部門
*
* @param wxDept 部門
* @return 結(jié)果
*/
@Override
public AjaxResult updateWxDept(WxDept wxDept) {
// 樂觀鎖操作步驟: 每次操作前都是先查詢、替換、最后更新, 否則樂觀鎖無效
// 1. 先查詢
WxDept dept = wxDeptMapper.selectWxDeptById(wxDept.getId());
log.info("查詢出來的數(shù)據(jù): {}", dept);
// 2. 替換
dept.setName("小賣鋪");
dept.setSn("sell");
// 3. 最后更新
int i = wxDeptMapper.updateWxDept(dept);
if (i > 0) {
return AjaxResult.success("樂觀鎖更新成功");
} else {
return AjaxResult.error("樂觀鎖更新失敗");
}
}7. 測試
7.1 查詢出id是1的數(shù)據(jù), 并修改數(shù)據(jù) name=小賣鋪, sn=sell


查詢出來的數(shù)據(jù): com.ruoyi.ruoyiwx.dept.domain.WxDept@861f795[ id=1 name=開發(fā)部 sn=dev version=0 ]
7.2 假設(shè)
7.1還沒更新時, 就有其它線程修改了id為1的數(shù)據(jù), 版本號version=1

7.3 上面7.1執(zhí)行update更新時就會失敗, 因為版本號version=1, 不是剛查詢出來的version=0

{
"msg": "樂觀鎖更新失敗",
"code": 500
}總結(jié):
1. 每次去拿數(shù)據(jù)的時候都會認(rèn)為別人不會修改數(shù)據(jù), 所以不會上鎖
2. 但是在更新的時候會判斷在此期間有沒有人去更新過這個數(shù)據(jù), 可以使用版本號version
到此這篇關(guān)于SpringBoot+MyBatisPlus中樂觀鎖的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)SpringBoot MyBatisPlus樂觀鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Java中Comparable 和 Comparator的用法
這篇文章主要介紹了關(guān)于Java中Comparable 和 Comparator的用法,Comparable 和 Comparator 是關(guān)于排序的兩個接口,用來實(shí)現(xiàn) Java 集合中的的排序功能,需要的朋友可以參考下2023-04-04
Java8 新特性Lambda表達(dá)式實(shí)例詳解
這篇文章主要介紹了Java8 新特性Lambda表達(dá)式實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03
java實(shí)現(xiàn)輸出字符串中第一個出現(xiàn)不重復(fù)的字符詳解
這篇文章主要介紹了java實(shí)現(xiàn)輸出字符串中第一個出現(xiàn)不重復(fù)的字符詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04
分布式醫(yī)療掛號系統(tǒng)Nacos微服務(wù)Feign遠(yuǎn)程調(diào)用數(shù)據(jù)字典
這篇文章主要為大家介紹了分布式醫(yī)療掛號系統(tǒng)Nacos微服務(wù)Feign遠(yuǎn)程調(diào)用數(shù)據(jù)字典,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-04-04
Spring中@EnableScheduling注解的工作原理詳解
這篇文章主要介紹了Spring中@EnableScheduling注解的工作原理詳解,@EnableScheduling是 Spring Framework 提供的一個注解,用于啟用Spring的定時任務(wù)(Scheduling)功能,需要的朋友可以參考下2024-01-01
Java使用Redis實(shí)現(xiàn)消息訂閱/發(fā)布的幾種方式
Redis 提供了 Pub/Sub (發(fā)布/訂閱) 模式,允許客戶端訂閱頻道并接收發(fā)布到這些頻道的消息,以下是 Java 中使用 Redis 實(shí)現(xiàn)消息訂閱的幾種方式,需要的朋友可以參考下2025-08-08
詳解如何給Sprintboot應(yīng)用添加插件機(jī)制
這篇文章主要為大家介紹了如何給 Sprintboot 應(yīng)用添加插件機(jī)制,文中有詳細(xì)的解決方案及示例代碼,具有一定的參考價值,需要的朋友可以參考下2023-08-08

