3、樂觀鎖
主要適用場景:當要更新一條記錄的時候,希望這條記錄沒有被別人更新,也就是說實現線程安全的數據更新
樂觀鎖實現方式:
- 取出記錄時,獲取當前version
- 更新時,帶上這個version
- 執行更新時, set version = newVersion where version = oldVersion
- 如果version不對,就更新失敗
(1)數據庫中添加version字段 執行如下sql語句
ALTER TABLE `user` ADD COLUMN `version` INT
(2)實體類添加version字段
並添加 @Version 註解
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;
(3)元對象處理器接口添加version的insert默認值
package com.mybatisplus.demo.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
//使用mp實現添加操作,這個方法執行
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
this.setFieldValByName("version",1,metaObject);
}
//使用mp實現修改操作,這個方法執行
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
特別說明:
- 支持的數據類型只有 int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整數類型下
newVersion = oldVersion + 1
newVersion
會回寫到entity
中- 僅支持
updateById(id)
與update(entity, wrapper)
方法 - 在
update(entity, wrapper)
方法下,wrapper
不能複用!!!
(4)在 MybatisPlusConfig 中註冊 Bean
package com.mybatisplus.demo.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.mybatisplus.demo.mapper")
public class MpConfig {
//樂觀鎖插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
(5)測試樂觀鎖可以修改成功
測試後分析打印的sql語句,將version的數值進行了加1操作
//測試樂觀鎖
@Test
public void testOptimisticLocker() {
//根據id查詢數據
User user = userMapper.selectById(1249658341914869761L);
//進行修改
user.setAge(200);
userMapper.updateById(user);
}