并发安全问题之超卖问题

并发安全问题之超卖问题

乐观锁总结:

优点 :不加锁性能好。
缺点 :同时请求成功率低(即只要发现数据变了就放弃了)。
乐观锁思想的具体体现 :一共两步,第一步,先查询状态。第二步,再更新数据时必须where等于前面的状态,确保数据没有改变。

第二步集查询和操作数据于一身具有原子性。

在有数量限制的业务中(即先查询的就是这个数据),要想提高成功率,可以在第二步中数据不必等于第一步查询的数据,而是小于第一步中查询的数据即可,这样就可以完美降低失败率,只有数量耗尽时才会失败。

**举个例子:**比如卖书,书有数量限制num_total=10,以卖出数量为num:

第一步查询:select * from book where id = xxx;

if (book.num < book.num_total) {可以继续执行第二步} else {拒绝卖书操作}

第二步查询加更新:update book set num = num + 1 where num < num_total;

第二步中没有使用标准的乐观锁即数据没有被操作才更新 (num = #{num})

而是让num < num_total只要没有达到库存上限即可操作,提高了并发的成功率,只要不是num=num_total都可以成功。

典型查询、判断、更新三个操作非原子性



解决方案-加锁即可,加锁的思想分为两类:悲观锁和乐观锁。

悲观锁是在操作数据之前先获取锁,有锁才能操作,这样安全了,但是性能下降了,把并发改为了单线程串行执行。
乐观锁不加锁,只会先查询一次,然后在操作数据时再查询一次(这里的查询与修改是原子性的,例如前面第一次查询变量a为1,等到操作数据时就要在SQL中update xxx set xxx=xxx where a = 1,这样就让查询和修改操作具有原子性),如果数据改变了就异常或者重试。







相关推荐
李慕婉学姐5 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆6 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin7 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20057 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉7 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国7 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882487 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈8 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_998 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹8 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理