点击商品秒杀按钮时的后台操作笔记

目录

点击商品秒杀时的(主要是减少数据库层面的访问)

最初

优化1

优化2

优化3(最终版本)


 

点击商品秒杀时的(主要是减少数据库层面的访问)

一步一步优化

最初

 判断数据库内存是否足够  足够再判断是否已经在订单表中存在(存在表示已经秒杀到了)  然后再进行订单创建以及库存的降低(这一步需要事务)

 

优化1

 判断数据库内存是否足够  足够再判断redis中是否存在把用户ID和商品ID作为key,订单信息为value的值(存在表示秒已经杀到了直接返回在Redis获取的订单信息)  然后再进行订单创建以及库存的降低和把用户ID和商品ID作为key放入redis(这一步需要事务)

优化2

 

把商品数量放到redis中

 

①:在初始化项目时,把商品数量放到Redis中

public class MiaoshaController implements InitializingBean {

 

@Autowired

RedisService redisService;

 

private HashMap<Long, Boolean> localOverMap =  new HashMap<Long, Boolean>();

 

/**

 * 系统初始化

 * */

public void afterPropertiesSet() throws Exception {

//数据库获取所有需要秒杀商品及其数量

List<GoodsVo> goodsList = goodsService.listGoodsVo();

if(goodsList == null) {

return;

}

for(GoodsVo goods : goodsList) {

redisService.set(GoodsKey.getMiaoshaGoodsStock,""+goods.getId(), goods.getStockCount());

}

}

②:判断Redis中商品数量是否足够  足够再判断redis中是否存在把用户ID和商品ID作为key,订单信息为value的值(存在表示秒已经杀到了直接返回在Redis获取的订单信息)  然后再进行订单创建以及库存的降低和把用户ID和商品ID作为key放入redis(这一步需要事务)

 

优化3(最终版本)

①:项目启动把商品库存数量放入redis中

②:收到请求,redis库存预减(使用内存标记可以降低redis访问),库存不足直接返回,库存足,进入第③步

private HashMap<Long, Boolean> localOverMap =  new HashMap<Long, Boolean>();

 

1  在第①步直接设置 每个商品内存标记  false表示还有商品数量

for(GoodsVo goods : goodsList) {

redisService.set(GoodsKey.getMiaoshaGoodsStock, ""+goods.getId(), goods.getStockCount());

localOverMap.put(goods.getId(), false);

}

 

2 预减redis库存时,如果没有商品数量 设置为true

//预减库存

     long stock = redisService.decr(GoodsKey.getMiaoshaGoodsStock, ""+goodsId);//10

     if(stock < 0) {

      localOverMap.put(goodsId, true);

     return Result.error(CodeMsg.MIAO_SHA_OVER);

     }

③:请求入队列,立即返回排队中

④:请求出队,减少库存生成订单(rabbitMQ  Direct模式)

Sender:

public void sendMiaoshaMessage(MiaoshaMessage mm) {

String msg = RedisService.beanToString(mm);

log.info("send message:"+msg);

amqpTemplate.convertAndSend(MQConfig.MIAOSHA_QUEUE, msg);

}

消费者:

@RabbitListener(queues=MQConfig.MIAOSHA_QUEUE)

public void receive(String message) {

log.info("receive message:"+message);

MiaoshaMessage  mm=RedisService.stringToBean(message, MiaoshaMessage.class);

MiaoshaUser user = mm.getUser();

long goodsId = mm.getGoodsId();

 

GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);

     int stock = goods.getStockCount();

     if(stock <= 0) {

     return;

     }

     //判断是否已经秒杀到了

     MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);

     if(order != null) {

     return;

     }

     //减库存 下订单 写入秒杀订单 处理完毕在redis中放入一个标识(是否成功或者失败)

     miaoshaService.miaosha(user, goods);

}

⑤:客户端轮训,判断是否秒杀成功

 

第④步进入队列后返回固定的码:0

0: 排队中

orderId:秒杀成功

-1 :秒杀失败

 轮训时需要新增加一个查询接口,查询redis 中当前商品+用户构成的key的value(也就是固定的码)。

回仓:30分钟不支付订单自动取消


30分钟以后,扫描下秒杀订单,看有哪些还没支付,把订单状态置为已经取消,可秒杀数量+1,redis的秒杀结束的标志位还原,内存的数量还原

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值