电商项目day19(秒杀功能实现)

本文详细介绍秒杀系统的实现思路,包括如何利用Redis缓存减少数据库压力,解决高并发下的秒杀排队和超卖问题,以及秒杀功能的前后端实现细节。同时,探讨了秒杀系统的优化方案,如防止重复购买、解决超卖、使用多线程提升MySQL处理效率,以及实现排队人数提醒。
该文章已生成可运行项目,

今日目标:

秒杀实现思路
    实现秒杀下单功能
    
    完成下单并发产生的订单异常问题  超卖
    完成高并发下用户下单排队和超限问题

一.秒杀的思路分析

1.需求分析:

所谓“秒杀”,就是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式。通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动。由于商品价格低廉,往往一上架就被抢购一空,有时只用一秒钟。

秒杀一共有,两种限制:库存限制和时间限制

需求:

(1)商家提交秒杀商品申请,录入秒杀商品数据,主要包括:商品标题、原价、秒杀价、商品图片、介绍等信息
(2)运营商审核秒杀申请
(3)秒杀频道首页列出秒杀商品(进行中的)点击秒杀商品图片跳转到秒杀商品详细页。
(4)商品详细页显示秒杀商品信息,点击立即抢购实现秒杀下单,下单时扣减库存。当库存为 0 或不在活动期范围内时无法秒杀。
(5)秒杀下单成功,直接跳转到支付页面(微信扫码),支付成功,跳转到成功页,填写收货地址、电话、收件人等信息,完成订单。

(6)当用户秒杀下单 5 分钟内未支付,取消预订单,调用微信支付的关闭订单接口,恢复库存。

数据库表的分析:

秒杀表的数据库表,我们不放在其他的商品表中,单独设计一个表结构

tb_seckill_goods表结构    

tb_seckill_order表主要是:秒杀成功后生成的订单

我们分析什么条件的商品的数据能够在秒杀页面展示?

     审核通过

      有库存

       当前实现大于开始时间,并小于秒杀结束时间   即正在秒杀的商品

 秒杀的实现思路分析:

         秒杀技术实现核心思想是运用缓存减少数据库瞬间的访问压力!读取商品详细信息时运用缓存,当用户点击抢购时减少缓存中的库存数量,当库存数为 0 时或活动期结束时,同步到数据库。 产生的秒杀预订单也不会立刻写到数据库中,而是先写到缓存,当用户付款成
功后再写入数据库。

       基于redis缓存,减少数据库的访问压力,在秒杀之前就将数据库的的数据放到缓存中

       秒杀开始后,用户抢购商品订单,下单成功后,减少库存,此时我们是操作redis中秒杀商品库存数据

那么我们在什么时候更新数据库的库存呢,      ----------------->redis库存为零,秒杀结束

使用redis缓存,单线程服务器,数据安全

定时任务spring-task实现:

定时任务主要常用的有两种:     spring - task     和quartz   

我们在这介绍spring  task   :

它可以说是轻量级的quartz    ,    主要配置文件和注解两种形式  

定时任务框架都是基于cron表达式完成定时时间指定。

往往都是6位字符
            Seconds Minutes Hours DayofMonth Month   DayofWeek 
                秒    分     时     月中某天   月     周中某天   
                
                每周一凌晨1点执行任务:0 0 1 ? * 2
                
                每天15点55分执行任务:0 55 15 * * ?
                
                每月6号凌晨执行任务:0 0 0 6 * ?
                
                每隔10秒多久执行一次:0/10 0 0 * * ?
                                    
            
    

本文章已经生成可运行项目
java实现秒杀系统@Controller @RequestMapping("seckill")//url:/模块/资源/{id}/细分 /seckill/list public class SeckillController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private SeckillService seckillService; @RequestMapping(value="/list",method = RequestMethod.GET) public String list(Model model){ //获取列表页 List list=seckillService.getSeckillList(); model.addAttribute("list",list); //list.jsp+model = ModelAndView return "list";//WEB-INF/jsp/"list".jsp } @RequestMapping(value = "/{seckillId}/detail",method = RequestMethod.GET) public String detail(@PathVariable("seckillId") Long seckillId, Model model){ if (seckillId == null){ return "redirect:/seckill/list"; } Seckill seckill = seckillService.getById(seckillId); if (seckill == null){ return "forward:/seckill/list"; } model.addAttribute("seckill",seckill); return "detail"; } //ajax json @RequestMapping(value = "/{seckillId}/exposer", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @ResponseBody public SeckillResult exposer(@PathVariable("seckillId") Long seckillId){ SeckillResult result; try { Exposer exposer =seckillService.exportSeckillUrl(seckillId); result = new SeckillResult(true,exposer); } catch (Exception e) { logger.error(e.getMessage(),e); result = new SeckillResult(false,e.getMessage()); } return result; } @RequestMapping(value = "/{seckillId}/{md5}/execution", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"} ) @ResponseBody public SeckillResult execute(@PathVariable("seckillId")Long seckillId,
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗的小巍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值