java控制订单过期时间_订单自动过期实现方案

需求分析:24小时内未支付的订单过期失效。

解决方案被动设置:在查询订单的时候检查是否过期并设置过期状态。

定时调度:定时器定时查询并过期需要过期的订单。

延时队列:将未支付的订单放入一个延时队列中,依次取出过期订单。

过期提醒:reids支持将一个过期的key(订单号)通知给客户端,根据过期的订单号进行相应的处理。

1. 被动设置

这个太简单了,就是在查询的时候判断是否失效,如果失效了就给他设置失效状态。但是弊端也很明显,每次查询都要对未失效的订单做判断,如果用户不查询,订单就不失效,那么如果有类似统计失效状态个数的功能,将会受到影响,所以只能适用于简单独立的场景。简直low爆了。

2. 定时调度

这种是常见的方法,利用一个定时器,在设置的周期内轮询检查并处理需要过期的订单。

具体实现有基于Timer的,有基于Quartz,还有springboot自带的Scheduler,实现起来比较简单。

就写一下第三个的实现方法吧:启动类加上注解@EnableScheduling

新建一个定时调度类,方法上加上@Scheduled注解,如下图那么简单。

91adaa98d531335a1565458faa8da86f.png

弊端不能够精准的去处理过期订单,轮询周期设置的越小,精准度越高,但是项目的压力越大,我们上一个项目就有这种状况,太多定时器在跑,项目运行起来比较笨重。

3. 延时队列

基于JDK的实现方法,将未支付的订单放到一个有序的队列中,程序会自动依次取出过期的订单。

如果当前没有过期的订单,就会阻塞,直至有过期的订单。由于每次只处理过期的订单,并且处理的时间也很精准,不存在定时调度方案的那两个弊端。

实现:

1.首先创建一个订单类OrderDelayDto需要实现Delayed接口。然后重写getDelay()方法和compareTo()方法,只加了订单编号和过期时间两个属性。

这两个方法很重要,

getDelay()方法实现过期的策略,比如,订单的过期时间等于当前时间就是过期,返回负数就代表需要处理。否则不处理。

compareTo()方法实现订单在队列中的排序规则,这样即使后面加入的订单,也能加入到排序中,我这里写的规则是按照过期时间排序,最先过期的排到最前面,这一点很重要,因为排在最前面的如果没有被处理,

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
商城会员积分过期实现方案可以通过以下步骤实现: 1. 定义积分类,包括积分值和过期日期等属性,可以使用 Java 中的类来实现。 ```java public class Point{ private int value; private Date expirationDate; public Point(int value, Date expirationDate){ this.value = value; this.expirationDate = expirationDate; } public int getValue(){ return value; } public Date getExpirationDate(){ return expirationDate; } } ``` 2. 在会员类中维护积分列表,包括添加积分和使用积分等方法,可以使用 List 来实现。 ```java import java.util.ArrayList; import java.util.Date; import java.util.List; public class Member{ private String name; private List<Point> points; public Member(String name){ this.name = name; points = new ArrayList<>(); } public void addPoint(int value, Date expirationDate){ Point point = new Point(value, expirationDate); points.add(point); } public void usePoints(int value){ List<Point> availablePoints = new ArrayList<>(); for(Point point : points){ if(!isExpired(point)){ availablePoints.add(point); } } availablePoints.sort((p1, p2) -> p1.getExpirationDate().compareTo(p2.getExpirationDate())); List<Point> usedPoints = new ArrayList<>(); for(Point point : availablePoints){ if(value <= 0){ break; } if(point.getValue() <= value){ usedPoints.add(point); value -= point.getValue(); } else{ Point newPoint = new Point(value, point.getExpirationDate()); usedPoints.add(newPoint); point.setValue(point.getValue() - value); value = 0; } } points.removeAll(usedPoints); } private boolean isExpired(Point point){ Date today = new Date(); return point.getExpirationDate().before(today); } } ``` 3. 在商城中,通过会员类来维护会员的积分,包括添加积分,使用积分等操作。 ```java import java.util.Date; public class ShoppingMall{ public static void main(String[] args){ Member member = new Member("张三"); member.addPoint(100, new Date(System.currentTimeMillis() + 30 * 24 * 3600 * 1000L)); // 添加100积分, 30天后过期 member.addPoint(50, new Date(System.currentTimeMillis() + 60 * 24 * 3600 * 1000L)); // 添加50积分, 60天后过期 member.usePoints(70); // 使用70积分 } } ``` 上述代码中,我们在商城中创建了一个会员对象 `member`,并向其添加了两个积分,分别是 100 分和 50 分,分别在 30 天和 60 天后过期。接着,我们使用 `usePoints` 方法来使用 70 分积分。由于 50 分积分在 70 分积分之前过期,因此我们会使用这个积分,并将剩余的 20 分积分从 100 分积分中使用。最后,我们从会员的积分列表中删除使用过的积分。 注意,在实现过程中,我们使用了 Java 中的 Date 类来表示过期日期,并且使用了 Lambda 表达式来简化排序代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值