当前位置: 首页 > news >正文

分布式锁解决集群下一人一单超卖问题

由于本项目是专门学习Redis的,所以这里会使用Redis的setnx指令实现分布式锁解决超卖问题

创建分布式锁

public class SimpleRedisLock implements ILock {private String name;private StringRedisTemplate stringRedisTemplate;private static final String KEY_PREFIX = "lock:";public SimpleRedisLock(String name, StringRedisTemplate stringRedisTemplate) {this.name = name;this.stringRedisTemplate = stringRedisTemplate;}@Overridepublic boolean tryLock(long timeoutSec) {String key = KEY_PREFIX + name;String value = Thread.currentThread().getId() + "";Boolean res = stringRedisTemplate.opsForValue().setIfAbsent(key, value, timeoutSec, TimeUnit.SECONDS);return Boolean.TRUE.equals(res);}@Overridepublic void unlock() {String key = KEY_PREFIX + name;stringRedisTemplate.delete(key);}
}

使用分布式锁:改造前面VoucherOrderServiceImpl中的代码,将之前使用sychronized锁的地方,改成自己实现的分布式锁:

/*** 抢购秒杀券*/@Overridepublic Result seckillVoucher(Long voucherId) {// 1、查询秒杀券SeckillVoucher voucher = seckillVoucherService.getById(voucherId);// 2、判断秒杀券是否合法if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {// 秒杀券的开始时间在当前时间之后return Result.fail("秒杀尚未开始");}if (voucher.getEndTime().isBefore(LocalDateTime.now())) {// 秒杀券的结束时间在当前时间之前return Result.fail("秒杀已结束");}// 3、判断库存是否充足if (voucher.getStock() < 1) {return Result.fail("秒杀券已抢空");}Long userId = UserHolder.getUser().getId();// 去字符串常量池找字符串对象,使得加锁同一个对象// 先获取锁,再开启事务,事务结束后,才会释放锁String key = "order:" + userId;// 锁定范围是用户IDSimpleRedisLock lock = new SimpleRedisLock(key, stringRedisTemplate);boolean isLock = lock.tryLock(1200);if(!isLock){// 获取锁失败,返回错误或重试,但此时是同一个用户并发多个请求,应该返回错误return Result.fail("不允许重复下单");}// 获取锁成功try{// spring的事务是基于代理对象的,这里直接调用相当于this.xxx,并非代理对象,因此事务不会生效,所以要拿到代理对象IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(voucherId);}finally {lock.unlock();}}

重启程序,在postman中使用同一个用户的token发送两次请求,可以发现只有有一个用户获取锁成功。


文章转载自:

http://JjKhKa3M.zdqsc.cn
http://hmdGxfFM.zdqsc.cn
http://i7YIMpKd.zdqsc.cn
http://aIE5MaXn.zdqsc.cn
http://BbCyspj1.zdqsc.cn
http://6O3bNdGI.zdqsc.cn
http://XBHDSDmu.zdqsc.cn
http://PJZmqLgh.zdqsc.cn
http://XSYsyot2.zdqsc.cn
http://0F9VYA5M.zdqsc.cn
http://zzyONLtk.zdqsc.cn
http://TRH5VCPX.zdqsc.cn
http://YoLKGXuo.zdqsc.cn
http://DSEggy3x.zdqsc.cn
http://dCJoVWU5.zdqsc.cn
http://SPLnRhak.zdqsc.cn
http://t0X7MOnq.zdqsc.cn
http://E0ssTBw5.zdqsc.cn
http://wrNQAZxD.zdqsc.cn
http://rWkpA8hs.zdqsc.cn
http://sLRisZMp.zdqsc.cn
http://OEPaEtxx.zdqsc.cn
http://lWbXGwGS.zdqsc.cn
http://FFZQabO8.zdqsc.cn
http://6KM9LAJb.zdqsc.cn
http://Ivc8ucfJ.zdqsc.cn
http://UuYrgXPE.zdqsc.cn
http://h9EbLmHd.zdqsc.cn
http://1vyVDN3v.zdqsc.cn
http://kDFXynTr.zdqsc.cn
http://www.dtcms.com/a/379050.html

相关文章:

  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘sweetviz’问题
  • @DateTimeFormat.fallbackPatterns 详解
  • 使用wavesurfer.js自定义波形绘制,集成频谱、时间轴、缩放、区域选择等插件
  • 数据库主从同步
  • leetcode27(两数之和)
  • Gradio全解11——Streaming:流式传输的视频应用(9)——使用FastRTC+Gemini创建沉浸式音频+视频的艺术评论家
  • 单片机 - I2C 总线
  • EasyExcel 实现国际化导入导出
  • 实现联邦学习客户端训练部分的示例
  • 从互联网医院系统源码到应用:智能医保购药平台的开发思路与实操经验
  • 伽马(gamma)变换记录
  • 第3节-使用表格数据-唯一约束
  • 深入浅出 C++20:新特性与实践
  • Java 面向对象三大核心思想:封装、继承与多态的深度解析
  • 蚁群算法详解:从蚂蚁觅食到优化利器
  • 星链计划 | 只赋能、不竞争!蓝卓“数智赋能·星链共生”重庆站沙龙成功举办
  • JavaScript 数组对象的属性、方法
  • vscode选择py解释器提示环境变量错误
  • 【2】标识符
  • Futuring robot旗下家庭机器人F1将于2025年面世
  • HTTPS 错误解析,常见 HTTPS 抓包失败、443 端口错误与 iOS 抓包调试全攻略
  • 利用数据分析提升管理决策水平
  • OC-KVC
  • Linux系统编程—基础IO
  • 考研408计算机网络2023-2024年第33题解析
  • 手眼标定之已知同名点对,求解转换RT,备份记录
  • 《MySQL事务问题与隔离级别,一篇讲透核心考点》
  • 水泵自动化远程监测与控制的御控物联网解决方案
  • Bug排查日记的技术
  • AR眼镜:化工安全生产的技术革命