使用延迟队列处理失效订单问题

在处理订单过程中,如果一个订单生成之后,在特定时间内(比如15分钟)没有付款,那么我们就要删除这一笔订单,释放占据的货物资源。在这种场景下,最直观的做法就是写一个定时job, 每分钟扫描一下数据库的订单表,如果订单超过了15分钟,那么订单状态改为删除,并且商品表数量要加1,因为刚刚删除的订单释放了一个商品。这样会给数据库造成很大的压力,而且如果长时间都没有过期的订单,而job依然会每分钟跑一次,浪费资源。

 

JDK的延时队列DelayQueue比较适应这种场景。延时队列,最重要的特性就体现在它的延时属性上,跟普通的队列不一样的是,普通队列中的元素总是等着希望被早点取出处理,而延时队列中的元素则是希望被在指定时间得到取出和处理,达到了规定的时间,则取出,没有达到规定的时间,则不取出。具体的代码逻辑如下。

 

1. 创建一个专门的DelayService, 它包含一个专门的延迟队列容器delayQueue. 它实现了InitializingBean接口,所以在初始化的时候,会执行afterPropertiesSet方法,调用start方法,启动一个线程, 这个线程会不断的从延迟队列中取出超时的消息,然后调用注册的listener方法进行处理。take方法获取并移除队列首元素,如果队列没有过期元素则等待,为阻塞式。

 

2. 可以在OrderService中注册对于超时消息的处理逻辑,也可以在其他地方注册,只要在容器初始化的时候,能把相应的listener注入到delayService的实例中。在订单超时后,这里会拿到超时订单的订单号,然后去数据库里做相应的操作,autoCancelOrder为取消订单,释放相应的货物。

3. 在用户创建订单的时候,会进行两个操作,在数据库中写入订单信息,然后就是在延迟队列容器中加入一个消息,这个消息要包含有创建的这个订单号码。delayService.add方法会把延迟消息放入到容器中。

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值