简介
意图:
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = yourVersion+1 where version = yourVersion
- 如果version不对,就更新失败
实现
插件配置
来到项目下的applicationContext.xml中配置sqlSessionFactoryBean的地方。
<!-- 配置SqlSessionFactoryBean
Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
-->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 别名处理 -->
<property name="typeAliasesPackage" value="com.badao.beans"></property>
<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>
<!-- 插件注册 -->
<property name="plugins">
<list>
<!-- 注册分页插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
<!-- 注册执行分析插件 -->
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
<property name="stopProceed" value="true" />
</bean>
<!-- 注册性能分析插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
<!-- 单位为毫秒 -->
<!-- <property name="maxTime" value="30" /> -->
<!--SQL是否格式化 默认false-->
<property name="format" value="true" />
</bean>
<!-- 注册乐观锁插件 -->
<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"></bean>
</list>
</property>
</bean>
添加Version
1.实体类添加Version
@Version
private Integer version;
并生成set和get方法
完整实体类
package com.badao.beans;
import java.io.Serializable;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.annotations.Version;
import com.baomidou.mybatisplus.enums.IdType;
import com.mchange.util.FailSuppressedMessageLogger;
@TableName(value="employee")
public class Employee extends Model<Model>{
@TableId(value="id",type=IdType.AUTO)
private Integer id;
//@TableField(value="last_name")
private String name;
private String email;
private Integer gender;
private Integer age;
@TableField(exist=false)
private String remark;
@Version
private Integer version;
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
/***
* 必须指定当前实体类的主键属性
*/
@Override
protected Serializable pkVal() {
// TODO Auto-generated method stub
return id;
}
}
2.数据库字段添加version
保存后给version赋值
3.测试
编写测试方法
/***
* 乐观锁插件
*/
@Test
public void testOptimisticLockerInterceptor() {
//更新操作
Employee employee = new Employee();
employee.setId(3);
employee.setName("OptimisticLockerInterceptor");
employee.setAge(23);
employee.setVersion(1);
employeeMapper.updateById(employee);
}
一定要设置版本!!! employee.setVersion(1);
运行结果
此时版本统一会成功更新。
更新成功后数据库的version字段会自动变成2。
假如此时另一个人也执行了更新操作,此时数据库的version会变成3。
然后自己再次进行更新时使用version为2去进行更新,结果:
更新了0条。