别再找了,创建订单30分钟未支付,这里有10种方案
大家好,我是飘渺。今天继续更新DDD&微服务专栏,本篇主要与大家探讨一下在Dailymart中如何定时关闭未支付的订单。
概述
之前的文章提及过,在DailyMart项目中,我们采用了预扣模式进行库存扣减。预扣模式的核心思想是在用户下单时提前扣减库存,在规定时间内完成支付,否则系统将释放预扣的库存。
这种模式的应用需要确保及时关闭未支付订单并释放库存,以避免商家出现库存不足导致少卖的问题。在系统开发中,类似的场景也有很多,例如到期自动收货、超时自动退款、下单后自动发送短信等。
本文旨在从这类业务问题出发,深入探讨可行的技术方案、实现细节,以及相关方案的优缺点。最后,将回顾DailyMart是如何解决这一问题的。由于篇幅有限,本文将主要聚焦于方案的阐述,而不涉及具体的代码实现。
一、定时任务
定时任务关闭订单是一个较为直观的方案,很多小型项目均是基于此方案实现。
具体实现是通过调度平台执行定时任务,扫描所有即将到期的订单并执行关单动作。这种方案的优势在于简单易实现,可基于Timer、ScheduledThreadPoolExecutor,或像xxl-job这类调度框架来实现。然而,此方案会存在以下几个问题:
1、时间不精准 :
定时任务基于固定的频率或时间执行,可能导致一些订单已经超时,但定时任务尚未触发,使得实际关闭时间延迟。
2、无法处理大订单量:
定时任务将关闭操作集中在一段时间内,当订单量较大时,任务执行时间可能较长,延迟订单扫描和关闭时间。
3、对数据库造成压力:
定时任务集中扫描数据库表,可能在短时间内占用大量数据库IO,若未进行良好隔离,可能影响线上正常业务。
4、分库分表问题:
在订单系统中,一旦订单量大就可能会考虑分库分表,而在分库分表中执行全表扫描,这是一个极不推荐的做法。