Redis分布式锁解决抢购问题
转:https://segmentfault.com/a/1190000011421467
废话不多说,首先分享一个业务场景-抢购。一个典型的高并发问题,所需的最关键字段就是库存,在高并发的情况下每次都去数据库查询显然是不合适的,因此把库存信息存入Redis中,利用redis的锁机制来控制并发访问,是一个不错的解决方案。
首先是一段业务代码:
@Transactional
public void orderProductMockDiffUser(String productId){
//1.查库存
int stockNum = stock.get(productId);
if(stocknum == 0){
throw new SellException(ProductStatusEnum.STOCK_EMPTY);
//这里抛出的异常要是运行时异常,否则无法进行数据回滚,这也是spring中比较基础的
}else{
//2.下单
orders.put(KeyUtil.genUniqueKey(),productId);//生成随机用户id模拟高并发
sotckNum = stockNum-1;
try{
Thread.sleep(100);
} catch (InterruptedExcption e){
e.printStackTrace();
}
stock.put(productId,stockNum);
}
}
这里有一种比较简单的解决方案,就是synchronized关键字。
public synchronized void orderProductMockDiffUser(String productId)
这就是java自带的一种锁机制,简单的对函数加锁和释放锁。但问题是这个实在是太慢了,感兴趣的可以可以写个接口用apache ab压测一下。
ab -n 500 -c 100 http://localhost:8080/xxxxxxx
下面就是redis分布式锁的解决方法。首先要了解两个redis指令
SETNX 和 GETSET,可以在redis中文网上找到详细的介绍。
SETNX就是set if not exist的缩写,如果不存在就返回保存value并返回1,如果存在就返回0。
GETSET其实就是两个指令GET和SET,首先会GET到当前key的值并返回,然后在设置当前Key为要设置Value。
首先我们先新建一个RedisLock类:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界