并发安全问题之超卖问题

并发安全问题之超卖问题

乐观锁总结:

优点 :不加锁性能好。
缺点 :同时请求成功率低(即只要发现数据变了就放弃了)。
乐观锁思想的具体体现 :一共两步,第一步,先查询状态。第二步,再更新数据时必须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,这样就让查询和修改操作具有原子性),如果数据改变了就异常或者重试。







相关推荐
辰烨chenye5 小时前
LeetCode Hot 100 题解 · 堆篇
java·算法·leetcode
shehuiyuelaiyuehao5 小时前
算法29,前缀和,除自身以外的数组的乘积
java·数据结构·算法
小刘在重生~6 小时前
Java常用类|String类详解 + BigDecimal精准计算(含面试题)
java·开发语言·python
随遇而安zx6 小时前
【多线程】---JMM 与 volatile 深度解析
java·多线程
邪修king6 小时前
Re:Linux系统篇(十九):进程篇(八): 进程等待详解:wait/waitpid,僵尸进程到底该如何回收
java·开发语言
啵啵啵鱼6 小时前
DS-顺序表
java·数据结构·笔记·后端·链表·obsidian
TinyMemory7 小时前
Java 面向对象核心入门(七):方法重载 Overload,同一个方法名能干不一样的活
java·面向对象·overload·方法重载
吴声子夜歌7 小时前
Java扩展——OkHttp
java·开发语言·okhttp
卓怡学长7 小时前
w210基于springboot反诈平台设计与实现
java·spring boot·spring·intellij-idea