如果由redis预先缓存user信息,和item信息相当于在第一步校验下单的过程省去了两次查表,这就极大的提升了下单的速度 。
@TransactionalpromoId非空表示已预约活动价格下单public OrderModel createOrder(Integer userId, Integer itemId, Integer promoId,Integer amount,String stockLogId) throws BusinessException {//1.校验下单状态,商品是否存在,用户是否合法,购买数量是否正确verifyingUserInformation(itemId,userId,amount,promoId);//2.落单减库存,支付减库存orderDecreaseStock(itemId, amount);//3.订单入库OrderModel orderModel = orderintoMysql(itemId, userId, amount, promoId);//4.返回前端return orderModel;}/**负责createOrder中的用户校验工作*/private void verifyingUserInformation(Integer itemId, Integer userId,Integer amount,Integer promoId) throws BusinessException {//这一步是没有缓存的直接查mysqlItemModel itemModel = itemService.getItemById(itemId);//这一步是走缓存的ItemModel itemModel = itemService.getItemByIdInCache(itemId);if (itemModel == null) {throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "商品信息不存在");}/**这个地方如果采用token登录模式这个地方是不用放进redis中进行验证user信息的,他这个采用的是oss模型所以需要* 将用户信息缓存在redis中提高效率UserModel userModel = userService.getUserById(userId);*/UserModel userModel = userService.getUserByIdInCache(userId);if (userModel == null) {throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "用户信息不存在");}if (amount <= 0 || amount > 99) {throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "数量信息不正确");}//校验活动信息if (promoId != null) {//校验对应活动是否存在这个适用商品if (!promoId.equals(itemModel.getPromoModel().getId())) {throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "活动信息不正确");} else if (itemModel.getPromoModel().getStatus() != 2) {//活动是否正在进行中throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "活动还未开始");}}}
/**用于商品活动缓存设置,因为生成订单需要两部分,第一部分需要验证商品,第二部分要验证用户*/@Overridepublic ItemModel getItemByIdInCache(Integer id) {ItemModel itemModel = (ItemModel) redisTemplate.opsForValue().get("item_validate_" + id);if (itemModel == null) {itemModel = this.getItemById(id);redisTemplate.opsForValue().set("item_validate_" + id, itemModel);redisTemplate.expire("item_validate_" + id, 10, TimeUnit.MINUTES);}return itemModel;}
@Overridepublic UserModel getUserByIdInCache(Integer id) {UserModel userModel = (UserModel) redisTemplate.opsForValue().get("user_validate_"+id);if(userModel == null){userModel = this.getUserById(id);redisTemplate.opsForValue().set("user_validate_"+id,userModel);redisTemplate.expire("user_validate_"+id,10, TimeUnit.MINUTES);}return userModel;}
2.redis实现扣减库存优化
如果每次下单都需要去数据库中去减库存,这样又1w条请求来,都要查询去更改同一件商品的stock数量,会很慢 。因为在更改数据的时候会触发行锁 。这样其他线程请求就需要去等当前线程更改完数据库才能进行更改,效率太低了 。
代码
.xml
如果我们直接用redis来进行更下单扣减库存操作呢?
1、redis先从数据库中取出库存数量
2、有下单请求时,每次来的请求都去扣减redis中的数量(因为redis是内存级别的效率非常高) 。
- 2023华为产品测评官活动火热开启——发出属于你的开发者之声,赢取丰厚奖品!
- 51cto首次户外纪实
- 跑步准备活动
- 转载 UCenter Home如何做线下活动
- 9月流量扶持活动入选名单出来啦!
- 三国中的名将颜良为何会被关羽秒杀?
- 美容店通过什么活动能最快吸引顾客?
- 企业私域流量活动参与率怎么提高?
- 受众同步管理功能上线,让你的活动礼包发对人
- 实用干货 高中数学,高考压轴三角形难题秒杀技巧