一、引言
先来大概普及一下数据库锁的概念,以下解释来源网络部分
悲观锁:时刻保持着一个悲观的态度,对谁都不信任,总想着别人会修改我的数据,所以为了防止别人修改,每次都会上锁,防止别人修改自己的数据。导致的后果就是每次想要拿到数据就必须要等待拿到锁,是一个很浪费时间的过程,如果访问量很大就是悲观锁一个致命的缺陷。
乐观锁:乐观锁对这个世界都很乐观,对每个想要获取数据的操作,他都会认为大家不会对自己的数据进行修改,所以不会上锁,在访问量很大的时候相比于悲观锁,节省了很多时间,用户不需要等待获取锁。
如果说大量读取数据操作的时候,适合使用乐观锁。如果冲突较多建议使用悲观锁。
悲观锁实现方式是数据库采用加锁的机制,而乐观锁最常见的手动就是通过版本号,每次更新的时候需要判断版本号是否一致,如果一致才能正常更新,反之更新失败。
二、具体现实
步骤一:配置乐观锁插件,这个采用的springboot的配置方式。
/**
* @Auther: IT贱男
* @Date: 2019/6/12 15:06
* @Description: MybatisPlus配置类
*/
@Configuration
public class MyBatisPlusConfig {
/**
* 乐观锁插件
* @return
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
步骤二:在实体类版本号的字段上加注解
/**
* 版本号
*/
@Version
private Integer version;
步骤三:测试调用,从SQL语句得出MP会把设置进去的版本号当作更新条件,并且版本号+1更新进去。
@Test
public void update(){
// 更新对象
User user = new User();
user.setEmail("[email protected]");
user.setId(1L);
// 需要把之前从数据库读出来的版本号设置进去
user.setVersion(1);
int update = userMapper.updateById(user);
System.out.println(update);
}
DEBUG==> Preparing: UPDATE sys_user SET email=?, update_time=?, version=? WHERE id=? AND version=? AND is_delete='0'
DEBUG==> Parameters: [email protected](String), 2019-09-19T16:00:38.149(LocalDateTime), 2(Integer), 1(Long), 1(Integer)
DEBUG<== Updates: 1
三、使用注意细节
细节一:支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
细节二:仅支持 updateById(id)
与 update(entity, wrapper)
方法
细节三:在 update(entity, wrapper)
方法下, wrapper
不能复用,这里小编给大家演示一下把,通过执行SQL语句看出,第一次更新是成功了,但是第二次更新失败了,在条件后面有两个版本号的条件。
扫描二维码关注公众号,回复:
10014746 查看本文章
@Test
public void updateByMyWrapper() {
// 条件构造器
QueryWrapper<User> wrapper = Wrappers.query();
wrapper.eq("name", "admin");
// 对象1
User user = new User();
user.setEmail("[email protected]");
user.setVersion(2);
userMapper.update(user,wrapper);
// 对象2
User user2 = new User();
user2.setEmail("[email protected]");
user2.setVersion(3);
// 注意,注意,这里的wrapper,和上面是是用的同一个
userMapper.update(user2,wrapper);
}
updateFill......
DEBUG==> Preparing: UPDATE sys_user SET email=?, update_time=?, version=? WHERE is_delete='0' AND name = ? AND version = ?
DEBUG==> Parameters: [email protected](String), 2019-09-19T16:06:26.172(LocalDateTime), 3(Integer), admin(String), 2(Integer)
DEBUG<== Updates: 1
updateFill......
DEBUG==> Preparing: UPDATE sys_user SET email=?, update_time=?, version=? WHERE is_delete='0' AND name = ? AND version = ? AND version = ?
DEBUG==> Parameters: [email protected](String), 2019-09-19T16:06:26.238(LocalDateTime), 4(Integer), admin(String), 2(Integer), 3(Integer)
DEBUG<== Updates: 0