时间:2021-05-20
所谓秒杀,就是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式。秒杀商品通常有两种限制:时间限制,库存限制,其中库存超卖问题是本教程的重点!
秒杀业务的运行流程主要可以分为以下几点:
商品表:
订单表:
秒杀技术实现核心思想是运用缓存减少数据库瞬间的访问压力。读取商品详细信息时要运用缓存,当用户点击抢购时也要运用缓存,减少缓存中的库存数量,当库存数为0时或活动时间结束才同步到数据库中。产生的秒杀预订单也不会立刻写到数据库中,而是先写到缓存,当用户付款成功后再写入数据库,或者异步写入MQ,让数据库根据自身的能力去消费。
缓存商品信息,库存信息
@Override @Transactional(rollbackFor = Exception.class) public GoodsEntity initGoods(String name, Integer amount, BigDecimal price) { GoodsEntity goodsEntity = new GoodsEntity().setName(name).setAmount(amount).setPrice(price).setStartDate(new Date()).setEndDate(new Date()); Assert.isTrue(goodsService.save(goodsEntity), "抢购商品初始化发生异常~"); // 缓存库存 redisTemplate.opsForValue().increment("amount:" + goodsEntity.getId(), amount); // 缓存商品信息 redisTemplate.opsForValue().set("goods:" + goodsEntity.getId(), goodsEntity); return goodsEntity; }基于redis incr 原子性防止超卖
@Override @Transactional(rollbackFor = Exception.class) public Boolean secKill(String key) { Long result = redisTemplate.opsForValue().decrement("amount:" + key, 1); if (result.compareTo(0L) >= 0) { // 下面的数据库操作建议走MQ让数据库按照他的处理能力,从消息队列中拿取消息进行处理。 Try.of(() -> { Assert.isTrue(goodsService.secKill(Long.valueOf(key)), "库存不足!"); OrderEntity orderEntity = new OrderEntity().setGoodsId(Long.valueOf(key)).setOrderNo(UUID.randomUUID().toString().replace("-", "")); Assert.isTrue(orderService.save(orderEntity), "订单创建发生异常~"); redisTemplate.opsForValue().set("secKill:" + orderEntity.getId(), orderEntity.getOrderNo(), 10, TimeUnit.SECONDS); return true; }).onFailure((e) -> { log.error("持久化异常:" + e.getMessage()); redisTemplate.opsForValue().increment("amount:" + key, 1); }); return false; } redisTemplate.opsForValue().increment("amount:" + key, 1); return false; }最终效果:
观察redis存储的数据和数据库的订单记录可发现,秒杀场景基本实现!
本文主要解决超卖,和长时间未支付库存重置的问题; 实际场景,还要考虑前后端的多种优化(静态页、cdn、防止重复下单、限流等等……)
前往下载
到此这篇关于Java基于redis和mysql实现简单的秒杀(附demo)的文章就介绍到这了,更多相关Java基于redis和mysql秒杀内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
1.简介分布式锁的方式有很多种,通常方案有:基于mysql数据库基于redis基于ZooKeeper网上的实现方式有很多,本文主要介绍的是如果使用mysql实现
本文实例为大家分享了php+redis消息队列实现抢购的具体代码,供大家参考,具体内容如下实现功能:1.基于redis队列,防止高并发的超卖2.基于mysql的
Linux安装好Redis之后,使用Java进行连接,Java代码如下packagecom.wzj.demo.test;importredis.clients.
本文是基于CentOS7.3系统环境,进行MySQL和Redis的安装和使用CentOS7.3Docker-ce一、安装MySQL镜像(1)拉取MySQL镜像d
jersey是基于Java的一个轻量级RESTful风格的WebServices框架。以下我基于IDEA实现Restful完整Demo。1.创建maven-we