SpringBoot整合MybatisPlus3.X之乐观锁(十三)
主要适用场景
意图:
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
乐观锁配置需要2步 记得两步
1.插件配置
spring xml: <bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>
spring boot: @Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
2.注解实体字段 @Version 必须要!
@Version
private Integer version;
特别说明:
支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
整数类型下
newVersion = oldVersion + 1newVersion会回写到entity中仅支持
updateById(id)与update(entity, wrapper)方法在
update(entity, wrapper)方法下,wrapper不能复用!!!
示例
示例Java代码(参考代码)
int id = 100;
int version = 2;
User u = new User();
u.setId(id);
u.setVersion(version);
u.setXXX(xxx);
if(userService.updateById(u)){
System.out.println("Update successfully");
}else{
System.out.println("Update failed due to modified by others");
}
示例SQL原理
update tbl_user set name = 'update',version = 3 where id = 100 and version = 2
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/p6spy/p6spy -->
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
<scope>test</scope>
</dependency>
<!-- for testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>配置类
@Configuration
public class MybatisPlusOptLockerConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
实体类
@Data
public class User {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@Version
private Integer version;
}Mapper
public interface UserMapper extends BaseMapper<User> {
}启动类
@SpringBootApplication
@MapperScan("com.mp.locker.mapper") //不加在容器里面获取不了
public class LockerApplication {
public static void main(String[] args) {
SpringApplication.run(LockerApplication.class, args);
}
}application.yml
spring:
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:h2:tcp://192.168.180.115:19200/~/mem/test
username: root
password: test测试类
@SpringBootTest
class LockerApplicationTests {
@Autowired(required = false)
UserMapper userMapper;
@Test
public void testUpdateByIdSucc() {
User user = new User();
user.setAge(18);
user.setEmail("test@baomidou.com");
user.setName("optlocker");
user.setVersion(1);
userMapper.insert(user);
Long id = user.getId();
//INSERT INTO user ( name, version, email, age ) VALUES ( 'optlocker', 1, 'test@baomidou.com', 18 )
User userUpdate = new User();
userUpdate.setId(id);
userUpdate.setAge(19);
userUpdate.setVersion(1);
//UPDATE user SET version=2, age=19 WHERE id=6 AND version=1
Assert.assertEquals("Should update success", 1, userMapper.updateById(userUpdate));
//6 optlocker 19 test@baomidou.com 2 值变成2
Assert.assertEquals("Should version = version+1", 2, userUpdate.getVersion().intValue());
}
@Test
public void testUpdateByIdFail() {
User user = new User();
user.setAge(18);
user.setEmail("test@baomidou.com");
user.setName("optlocker");
user.setVersion(1);
//INSERT INTO user ( name, version, email, age ) VALUES ( 'optlocker', 1, 'test@baomidou.com', 18 )
userMapper.insert(user);
Long id = user.getId();
User userUpdate = new User();
userUpdate.setId(id);
userUpdate.setAge(19);
userUpdate.setVersion(0);
//UPDATE user SET version=1, age=19 WHERE id=7 AND version=0
userMapper.updateById(userUpdate);
}
@Test
public void testUpdateByIdSuccWithNoVersion() {
User user = new User();
user.setAge(18);
user.setEmail("test@baomidou.com");
user.setName("optlocker");
user.setVersion(1);
userMapper.insert(user);
Long id = user.getId();
User userUpdate = new User();
userUpdate.setId(id);
userUpdate.setAge(19);
userUpdate.setVersion(null);
Assert.assertEquals("Should update success as no version passed in", 1, userMapper.updateById(userUpdate));
User updated = userMapper.selectById(id);
Assert.assertEquals("Version not changed", 1, updated.getVersion().intValue());
Assert.assertEquals("Age updated", 19, updated.getAge().intValue());
}
/**
* 批量更新带乐观锁
* <p>
* update(et,ew) et:必须带上version的值才会触发乐观锁
*/
@Test
public void testUpdateByEntitySucc() {
QueryWrapper<User> ew = new QueryWrapper<>();
ew.eq("version", 1);
int count = userMapper.selectCount(ew);
User entity = new User();
entity.setAge(28);
entity.setVersion(1);
Assert.assertEquals("updated records should be same", count, userMapper.update(entity, null));
ew = new QueryWrapper<>();
ew.eq("version", 1);
Assert.assertEquals("No records found with version=1", 0, userMapper.selectCount(ew).intValue());
ew = new QueryWrapper<>();
ew.eq("version", 2);
Assert.assertEquals("All records with version=1 should be updated to version=2", count, userMapper.selectCount(ew).intValue());
}
}
SpringBoot整合MybatisPlus3.X之乐观锁(十三)的更多相关文章
- SpringBoot整合MyBatis-Plus3.1详细教程
作者:Sans_ juejin.im/post/5cfa6e465188254ee433bc69 一.说明 Mybatis-Plus是一个Mybatis框架的增强插件,根据官方描述,MP只做增强不做改 ...
- SpringBoot整合MybatisPlus3.X之SQL执行分析插件(十四)
pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...
- SpringBoot整合MybatisPlus3.X之自定义Mapper(十)
pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...
- SpringBoot整合MybatisPlus3.X之SQL注入器(九)
pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...
- SpringBoot整合MybatisPlus3.X之Wrapper(五)
官方文档说明: 以下出现的第一个入参boolean condition表示该条件是否加入最后生成的sql中 以下代码块内的多个方法均为从上往下补全个别boolean类型的入参,默认为true 以下出现 ...
- SpringBoot整合MybatisPlus3.X之分页插件(四)
注:详细请看2.X博客中,3.X直接上代码. 建议装一个MybatisX插件,可以在Mapper和Xml来回切换 pom.xml <dependencies> <dependency ...
- SpringBoot整合MybatisPlus3.X之逻辑删除(三)
pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...
- SpringBoot整合MybatisPlus3.X之Sequence(二)
数据库脚本 DELETE FROM user; INSERT INTO user (id, name, age, email) VALUES (, , 'test1@baomidou.com'), ...
- SpringBoot整合Mybatisplus3.x之CRUD(一)
pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...
随机推荐
- CSS div仿table样式
要想让div元素显示的样式与table相同,那么需要使用display属性,这个属性将告诉浏览器这些数据是制表的,将以哪种样式来渲染数据: // table --使该元素按table样式渲染 // t ...
- 原创电子书《菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师》
<菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师> 国庆节快乐!一年一度长度排第二的假期终于来了. 难得有十一长假,作者也想要休息几天啦. 不管你是选择出门玩,还是在公司加班,在学 ...
- jetbrains全系列可用2018
转自 https://blog.csdn.net/u014044812/article/details/78727496 仅记录前两种方法 1.授权服务器激活 优点:方便快捷 缺点:激活的人数多了就容 ...
- 【Oracle】SQL语句优化
(1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最 ...
- Inkscape 旋转并复制
画一个图形,点击图标. 然后图标中心有个十字叉, 然后把这个十字叉拖到你想要旋转的地方. 然后shift+ctrl+m打开变换菜单. 选择旋转选项卡,然后设置角度,点击应用.就可以旋转了,如果配合ct ...
- LitePal的存储操作
传统的存储数据方式 其实最传统的存储数据方式肯定是通过SQL语句拼接字符串来进行存储的,不过这种方式有点过于“传统”了,今天我们在这里就不讨论这种情况.实际上,Android专门提供了一种用于存储 ...
- 关于jQery中$.Callbacks()的理解
$.Callbacks()主要使用了回调,而说到回调又不得不说javascript的事件循环机制了. 所以想了解回调最好先看看js运行机制. $.Callbacks()可以理解为创建一个回调队列 va ...
- 一文了解 Redis 内存监控和内存消耗
Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多.所以,监控 Redis 的内存消耗并了解 Redis 内存模型对高效并长期稳定使用 Redis ...
- python自动化测试三部曲之request+django实现接口测试
国庆期间准备写三篇博客,介绍和总结下接口测试,由于国庆期间带娃,没有按照计划完成,今天才完成第二篇,惭愧惭愧. 这里我第一篇博客的地址:https://www.cnblogs.com/bainianm ...
- Vue-cli父子组件之间传参
一.父传子( 先写父组件 父组件 <template> <子组件 :子组件的变量名='父组件的变量'> </子组件> //子组件的变量名前的冒号千万别丢了有和没有是 ...