实现步骤

step1:添加乐观锁拦截器

MP的其他拦截器功能可以参考官网

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}

step2:配置Entity

@TableField(fill = FieldFill.UPDATE)
@Version
private Date updateTime;

用更新字段充当版本号。

  • 上面的配置需要注意的是:updateTime既配置自动填充,又配置了乐观锁功能。MP在进行处理时会先进行乐观锁处理,然后再进行自动填充。
  • 问题:前端送了id和一些需要更新的字段过来,每次需要从数据库中查出version,然后再进行更新(要么前端将版本号传过来);
  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime;
  • 仅支持 updateById(id) 与 update(entity, wrapper) 方法,在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
  • 对于updateTime这个字段,在数据库中建议设置成时区不相关的时间戳类型。

多说一点

使用updateTime作为版本号可能会存在一些问题。

我们通常需要将updateTime返回给前端页面,假如我们不做任何设置,返回前端的数据大概是下面的样子:

{
"userId": 367,
"address": "上海市自由之路xxxxxx...",
"workUnit": "XXXX",
"createTime": "2020-12-22T00:00:00.000+08:00",
"updateTime": "2021-01-08T17:28:14.782+08:00"
}

这种时间格式可能不是前端页面需要的,这是我们可以进行如下设置;

spring:
jackson:
default-property-inclusion: non_null
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss

返回的数据

{
"userId": 367,
"address": "上海市自由之路xxxxxx...",
"workUnit": "XXXX",
"createTime":"2020-12-22 00:00:00",
"updateTime":"2021-01-08 17:28:14"
}

经过这个配置后,就可以得到可读性比较好的时间格式了。但是我们需要注意的时候,这个时间的精度其实已经丢失了,当前提交修改数据到后端,这个值和数据库中的值已经不相等了。所以永远不能将数据更新成功。

所以这种情况下使用updateTime来进行乐观锁更新就不太适合了。可以考虑在表中另外加一个字段version来进行乐观锁更新。

但其实还是有比较好的解决办法的。

首先,我们不要对返回的时间格式进行全局话配置。

spring:
jackson:
default-property-inclusion: non_null
time-zone: GMT+8
# date-format: yyyy-MM-dd HH:mm:ss

然后,添加一个updateTime的备份字段updateTimeSimpleFormat,并对这个字段进行单独的时间格式化。

private Date updateTime;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTimeSimpleFormat;

updateTimeSimpleFormat不要生成get和set方法,在updateTime的set方法中对updateTimeSimpleFormat进行赋值。

public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
this.updateTimeSimpleFormat = updateTime;
}

这样就既能满足前端返回格式化的时间,后端又能获取到乐观锁的版本号。

但是,这个方法比较不好的地方,就是必须对每个时间格式进行@JsonFormat注解配置,不能进行全局配置,比较繁琐。

总结:使用updateTime作为乐观锁的优点就是不需要再新加字段,比较简洁。但是带来的问题上面已经讲的很清楚了。还是印证了那个真理:没有完美的技术,只有适合的技术。

MP(MyBatis-Plus)实现乐观锁更新功能的更多相关文章

  1. mybatis 如何使用乐观锁

    悲观锁的问题: 因为悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性.如果加锁的时间过长,其他用户长时间无法访问,影响了程序的并发访问性,同时这样对数据库性能开销影响也很大,特别是 ...

  2. 阶段3 1.Mybatis_12.Mybatis注解开发_3 mybatis注解开发保存和更新功能

    使用直接来实现CRUD操作 Insert方法 创建测试类 把变量都定义在外面 写测试方法 修改链接的数据库 update方法 再加上address 被更新的数据

  3. xorm - Update,乐观锁,更新时间updated,NoAutoTime()

    更新数据使用Update方法 Update方法的第一个参数为需要更新的内容,可以为一个结构体指针或者一个Map[string]interface{}类型. 当传入的为结构体指针时,只有非nil和非0的 ...

  4. 【mybatis-plus】什么是乐观锁?如何实现“乐观锁”

    "乐观锁"这个词以前我也没听过.上次在测试需求的时候,查询数据库发现有一个version字段,于是请教开发这个字干嘛使, 人家回复我:乐观锁,解决并发更新用的.当时大家都忙,咱也不 ...

  5. Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--悲观锁( ...

  6. MySQL 乐观锁与悲观锁

    悲观锁 悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁. 悲观锁: ...

  7. 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景   Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...

  8. Mysql共享锁、排他锁、悲观锁、乐观锁

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--间隙锁( ...

  9. 写了一个 gorm 乐观锁插件

    前言 最近在用 Go 写业务的时碰到了并发更新数据的场景,由于该业务并发度不高,只是为了防止出现并发时数据异常. 所以自然就想到了乐观锁的解决方案. 实现 乐观锁的实现比较简单,相信大部分有数据库使用 ...

随机推荐

  1. PyQt学习随笔:Model/View开发时在view数据项中设置不同角色数据的方法

    在往Model中通过QStandardItem等类插入数据项时,除了实际插入的存储数据,还可以设置不同角色(请参考<PyQt学习随笔:Model/View中诸如DisplayRole的数据角色及 ...

  2. pycharm 本地代码同步到github上

    第一步, pycharm中setting-> Version Control -> Github -> addacount 如果账号密码登录不成功,就用token登录,参考下面这个博 ...

  3. 串口数据监视-Bus Hound

    Bus Hound使用说明 一.打开该工具,会看到最上面的六个图标:1.Capture(捕捉按钮):按下它选择捕捉数据界面2.Save(保存按钮):按下它选择保存数据界面3.Setting(设置按钮) ...

  4. 写给OIer们的一些话(修订版)

    我是一个高二的OIer,离我正式退役的日子已经不超过一年了.在这个时期,与其写一些回忆性的文字,不如跳出"自我"的范畴,以一种比较全局的角度和大家一起分享一些我对OI的认知和看法. ...

  5. maven私有仓库搭建(nexus)

    搭建是参考博客:https://blog.csdn.net/zn353010922/article/details/79441122 切换到nexus目录的bin下 启动.状态.停止:./nexus ...

  6. CentOS7搭建Hadoop-3.3.0集群手记

    前提 这篇文章是基于Linux系统CentOS7搭建Hadoop-3.3.0分布式集群的详细手记. 基本概念 Hadoop中的HDFS和YARN都是主从架构,主从架构会有一主多从和多主多从两种架构,这 ...

  7. 1.微博回调接口 和绑定user接口

    1.1 oauth/views.py 中添加试图函数 http://192.168.56.100:8888/oauth/weibo/callback/ # 通过vue前端传入的code,微博身份验证c ...

  8. Java中中文排序器

    在Java中使用Collator类按照汉字拼音排序字符串 public static void main(String[] args) throws Exception{ String[] strs ...

  9. 【PY从0到1】第二节 字符串和数字

    #本课程都以代码形式呈现.现在进入Python的基础内容的学习. #由于本课程是从0开始分享,所以Python的基础内容是必不可少的.这也是Python量化的必经之路. #下面进入正题. #一般用'# ...

  10. 一段小代码秒懂C++右值引用和RVO(返回值优化)的误区

    关于C++右值引用的参考文档里面有明确提到,右值引用可以延长临时变量的周期.如: std::string&& r3 = s1 + s1; // okay: rvalue referen ...