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

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

 

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

 

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

 

使用延迟队列处理失效订单问题_第1张图片

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

使用延迟队列处理失效订单问题_第2张图片

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

使用延迟队列处理失效订单问题_第3张图片

使用延迟队列处理失效订单问题_第4张图片

 

 

你可能感兴趣的:(技术积累)