MP(MyBatis-Plus)实现乐观锁更新功能
实现步骤
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)实现乐观锁更新功能的更多相关文章
- mybatis 如何使用乐观锁
悲观锁的问题: 因为悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性.如果加锁的时间过长,其他用户长时间无法访问,影响了程序的并发访问性,同时这样对数据库性能开销影响也很大,特别是 ...
- 阶段3 1.Mybatis_12.Mybatis注解开发_3 mybatis注解开发保存和更新功能
使用直接来实现CRUD操作 Insert方法 创建测试类 把变量都定义在外面 写测试方法 修改链接的数据库 update方法 再加上address 被更新的数据
- xorm - Update,乐观锁,更新时间updated,NoAutoTime()
更新数据使用Update方法 Update方法的第一个参数为需要更新的内容,可以为一个结构体指针或者一个Map[string]interface{}类型. 当传入的为结构体指针时,只有非nil和非0的 ...
- 【mybatis-plus】什么是乐观锁?如何实现“乐观锁”
"乐观锁"这个词以前我也没听过.上次在测试需求的时候,查询数据库发现有一个version字段,于是请教开发这个字干嘛使, 人家回复我:乐观锁,解决并发更新用的.当时大家都忙,咱也不 ...
- Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景
一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--悲观锁( ...
- MySQL 乐观锁与悲观锁
悲观锁 悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁. 悲观锁: ...
- 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景
浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...
- Mysql共享锁、排他锁、悲观锁、乐观锁
一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--间隙锁( ...
- 写了一个 gorm 乐观锁插件
前言 最近在用 Go 写业务的时碰到了并发更新数据的场景,由于该业务并发度不高,只是为了防止出现并发时数据异常. 所以自然就想到了乐观锁的解决方案. 实现 乐观锁的实现比较简单,相信大部分有数据库使用 ...
随机推荐
- PyQt(Python+Qt)学习随笔:Designer中ItemViews类部件的frameShadow属性
老猿Python博文目录 老猿Python博客地址 frameShadow属性是从QFrame继承的属性,对应类型为QFrame.Shadow,该属性表示框架提供三维效果的阴影类型,有如下取值: 可以 ...
- PyQt(Python+Qt)学习随笔:部件拉伸策略sizePolicy优先级
部件的尺寸调整策略或拉伸策略sizePolicy有7个值,如果同一个布局中的不同部件设置了不同的拉伸策略策略,在整个布局空间拉伸时,它们会怎么进行拉伸处理呢? 在未设置拉伸因子的情况下,Qt中这些拉伸 ...
- 攻防世界 web进阶区 ics-06
攻防世界 ics-06 涉及知识点: (1)php://filter协议 (2)php中preg_replace()函数的漏洞 解析: 进入题目的界面,一通乱点点出了唯一一个可以进入的界面. 观察ur ...
- python调用jar包
工作项目中用jmeter做接口测试,想尝试用python写接口测试(练习下python), 接口中好多字段都需要加密,而加密方法是java开发写的,打的jar包,这就需要考虑python调用java: ...
- Elements-of-Python_03_LanguageFeature
(内容包括Python语法概述,流程控制,条件表达式) 1 Python语法 1.1 Python的特点 Python是一种完全面向对象的.解释性的.可移植的.开源的脚本编程高级语言,具有丰富的库,允 ...
- 3、tensorflow变量运算,数学运算
import tensorflow as tf import numpy as np a = tf.range(1,7) a = tf.reshape(a,[2,3]) b = tf.constant ...
- AH/HNOI 2017 礼物
题目链接 描述 两个序列 \(x, y\),可以将一个序列每个值同时加非负整数 \(c\),其中一个序列可以循环移位,要求最小化: \[\sum_{i = 1}^{n}(x_i - y_i) ^ 2 ...
- STL——容器(Set & multiset)的删除 erase
set.clear(); //清除所有元素 set.erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器. set.erase(beg,end ...
- 【Ubantu 系统显示ip为127.0.0.1 解决办法】
现象:Ubantu : >>>ifconfig Link encap:以太网 硬件地址****************** inet 地址:127.0.0. ...
- 二、初步认识LoadRunner工具
LoadRunner工具有三个组成分别是: Virtual User Generator:用户行为模拟:录制运行脚本. Controller:上面的录制一个用户操作,这个可以将其克隆成多个用户,模拟多 ...