前言:
乐观锁/悲观锁毫无疑问是面试经常被问到的,那么什么是乐观锁/悲观锁?
乐观锁,就是非常乐观,无论做什么事都不会去上锁,仅在最后提交时采取做检查(是否有其它线程更改了他的资源)
悲观锁,悲观的态度,无论做什么事都会上锁(事情可以理解为事务),再去操作,这无疑很严谨,但也是浪费了资源
注意:并发问题的解决方式只能是变为串行
此篇主要讲解结合MybatisPlus的乐观锁机制
mybatisPlus的乐观锁插件
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
使用方法
说明:
- 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整数类型下
newVersion = oldVersion + 1
newVersion
会回写到entity
中- 仅支持
updateById(id)
与update(entity, wrapper)
方法 - 在
update(entity, wrapper)
方法下,wrapper
不能复用!!!
mybatisPlus乐观锁插件的工作流程
先查询,获得版本号 version = 1(就是当前版本),用来判定是否有其它线程抢占这个资源,如果有,就更新失败,抢占线程更新成功!!
测试MybatisPlus乐观锁字段
1,数据库加字段(用作版本控制),默认值设为1
2,实体添加对应的字段映射
3,注册乐观锁插件
既然是乐观锁插件,自然要去配置bean
注意:我这里用到是3.0.4版本,如果是3.4.0版本可以去mybatisPlus官网找最新配置类相关代码
现在,mybatisPlus的乐观锁插件就已经配置好了
测试
数据库变化:
解释:
此时的变化正好与不加乐观锁的情况相反,先抢占资源的线程更新数据成功,说明version(乐观锁版本控制成功实现),其原理就是当多个线程同时对一个资源进行操作时,那么后台会根据version去判断当前版本,如果当前版本没有version+1,就证明当前线程对资源的操作已经被别的线程给抢占了,所以会操作失败,这也就是乐观锁的作用,