红包(商品)库存秒杀系统
来源:互联网 发布:柠檬网络tv 编辑:程序博客网 时间:2024/04/29 00:46
下面是我的设计思路:
有不妥的地方请帮忙指正!
1,第一次将mysql中的库存数据取出放入redis缓存中
2,并发请求的时候,每一个线程进来自动将redis中的库存自动-1(redis的自减操作为原子操作),然后判断结果是否>=0
3,当结果>=0说明该线程有资格获得红包(线程进来就分配库存,<0 肯定是库存不足的情况)
4,有资格获得红包的用户 执行获得红包的操作(如果获得失败,将redis中的库存+1)
5,当步骤3 判断已经没有库存的时候,应该要将redis中的库存+1 ;(因为会过一段时间同步的mysql数据库中,要保证redis中的数据准确性)
6,当有线程进来领取红包的时候,说明库存有了变化,则插一条异步请求 :同步数据到mysql的接口 (并且是5分钟之后执行)
7,针对单个用户多并发的情况,只有将用户的ID+红包的ID作为主键存在redis中,并且设置有效时间为3秒(多少秒根据需求设定,比如这里是,在3秒里面我只接受你一次请求)第一个线程进来reids 线程数=1,后面进来的自增;有且只有redis线程数=1的时候,才让线程往下面走;
总结:利用redis的自增自减操作的原子性;将库存的读写操作在某个时间点执行,并不需要每次变更都去读写数据库(这样对性能影响很大);同步操作异步执行;
下面是示例部分代码:
private boolean receiveCoupon (String userId ,long templateId ) throws BusinessException { boolean flag = false; long count = 0; count = jedisService .incrCounterCache( "cpsCoupon" +templateId , userIdOrtelphone , 1); if (count > 0) { //一个用户一个模板3秒内只能领取一次,预防并发问题 jedisService .expire("cpsCoupon" +templateId , userIdOrtelphone , 3);//expire是设置缓存有效期 } ); if (count == 1) { flag = insertCouponNew(userId,templateId); } return flag ; }
private boolean insertCouponNew(String userId,long templateId ) throws BusinessException { //做一些校验判断 ........ //检查库存并且发送红包 checkRepertoryAndSend(userId,templateId); return true ; }
public void checkRepertoryAndSend (String userId ,long templateId ) throws BusinessException { //从数据库查询 红包库存 ccTmplate.getRepertory() 是库存 ........ //判断缓存中有没有库存的数据,如果没有,就将查出来的放进缓存 Object rep = jedisService .exists(AppCacheEnum. COUPON_REPERTORY.toString(), templateId ); if (!(boolean )rep ){ int ttl = 60*60*24*30*12; // 存个一年; jedisService .putCounterCache(AppCacheEnum. COUPON_REPERTORY.toString(), templateId , ccTmplate .getRepertory(), ttl); } //每个线程进程进来都自动-1;分配一个库存;incrCounterCache 就是redis 的incr操作,它是原子操作 if (jedisService.incrCounterCache(AppCacheEnum. COUPON_REPERTORY .toString(),templateId ,-1)>=0){ //有库存可以购买 //这里执行发放红包操作;如果红包发放是吧 则需要将缓存-1 jedisService .incrCounterCache(AppCacheEnum. COUPON_RECEIVE_NUM.toString(), templateId ,1); //同步任务 当第一个线程进来,缓存COUPON_KC_SYNC执行自增操作==1;则发一个同步的操作,并且设置为5分钟之后执行 if (jedisService .incrCounterCache(AppCacheEnum. COUPON_KC_SYNC.toString(), templateId ,1)==1){ int ttl = 300; //这个缓存的主要目的就是来判断时间是否过了5分钟 jedisService .expire(AppCacheEnum. COUPON_KC_SYNC.toString(), templateId ,ttl ); //加上同步任务并且是5分钟之后 SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss" ); Date time = DateUtil.getDateByAdd( "n" , 5, new Date());//5分钟之后同步一下分钟 Long focusVal = Long.valueOf( formatter.format( time )); //下面是插入一条定时任务,在5分钟之后执行的同步库存操作 ...... 这个定时任务就不详细说了; } } else { //刚刚减掉了 这里没发红包库存给加回来 jedisService .incrCounterCache(AppCacheEnum. COUPON_REPERTORY.toString(), templateId ,1); //判处库存不足的异常 throw new BusinessException(BusinessCode.coupon_has_clear .getCode(),BusinessCode. coupon_has_clear.getMsg()); } }
public int syncRepertory (long id ){ return cpsCouponTemplateMapper .syncRepertory( id,库存数量); }
0 0
- 红包(商品)库存秒杀系统
- PHP相关系列 - 商品秒杀库存问题
- PHP相关系列 - 商品秒杀库存问题
- PHP相关系列 - 商品秒杀库存问题
- 商品库存管理系统
- 如何设计一个小而美的秒杀系统(抢红包)?
- 商品秒杀细节
- ecshop商品秒杀
- 商品秒杀
- MVC大型商贸系统(库存管理)技术解释(四) 商品调拨
- MVC大型商贸系统(库存管理)技术解释(六)商品返仓
- MVC大型商贸系统(库存管理)技术解释(七) 商品转库
- 商品库存清单案例(Java)
- PHP商品秒杀倒计时
- redis秒杀商品队列
- JS demo商品秒杀
- 用C语言编写的商品库存管理系统
- OpenCart 2.x 系统商品数量库存减少逻辑
- HDU 3658 How many words (矩阵快速幂&递推)
- 小字符喷码机和高解析喷码机的区别
- 树莓派IoT 学习3 修改静态ip
- C/Python实现的一道笔试题
- 插件式开发(一)-----已安装
- 红包(商品)库存秒杀系统
- Mybatis数据操作
- MapReduce程序的3种集群提交运行模式详解---基于Windows与Linux两种开发环境
- shader 是什么————图形学的入门课
- 喷码机配合厂线进行标识方案
- jsp学习总结
- LDA
- GNU C 、ANSI C、标准C、标准c++区别和联系
- leetcode 334. Increasing Triplet Subsequence