前言设计订单过期,不能单纯靠redis,需要兜底策略
代码实现:import com.coolplay.trade.dto.req.cancelorderreq;import lombok.extern.slf4j.slf4j;import org.apache.commons.collections.collectionutils;import org.springframework.data.redis.core.zsetoperations;import org.springframework.scheduling.annotation.scheduled;import org.springframework.stereotype.service;import javax.annotation.resource;import java.util.set;import java.util.concurrent.timeunit;@service@slf4jpublic class orderredisdelayqueueoperator extends abstractorderscheduledelayqueue { @resource(name = "redistemplate") private zsetoperations<string, string> orderredis; /** * 预售、现货生成订单15分钟后未支付,需要取消订单 */ private static final string delay_queue_name = "order"; /** * 每1秒执行一次 */ @override @scheduled(cron = "0/1 * * * * ? ") public void ordereventprocess() { if (!redislock.trylock(this.getclass().getsimplename(), timeunit.milliseconds, 10, 100)) { return; } set<string> dq = orderredis.range(delay_queue_name, 0l, long.max_value); if (collectionutils.isempty(dq)) { return; } for (string orderno : dq) { double xs = orderredis.score(delay_queue_name, orderno); double now = system.currenttimemillis() * 1.0; if (xs <= now) { log.info("{} timed out", orderno); super.threadpooltaskexecutor.execute(() -> { cancelorderreq req = new cancelorderreq(); req.setorderno(orderno); req.setcanceltype(orderactionenum.time_out_cancel); orderservice.cancelorder(req); }); } else { //log.info("{} no time out", orderno); //如果最小的都没有过期,剩余的则不用处理了 break; } } } public void addtoredis(string orderno, long delaytime) { orderredis.add(delay_queue_name, orderno, delaytime * 1.0); } public void removefromredis(string orderno) { orderredis.remove(delay_queue_name, orderno); }}
兜底策略/** * 取消订单--10分钟--20分钟执行一次 */ @xxljob("cancelorder20minutes") public void cancelordertenminutes() { log.info("*****[开始:下单十分钟以后系统自动取消订单]*****"); date start = dateutil.dateroll(new date(), calendar.minute,-20); date end = new date(); list<clorder> clorderlist =clordermapper.selectlistallordrwaiting(start,end); if(objectutil.isnotempty(clorderlist)){ for(int i=0;i<clorderlist.size();i++){ clorder clorder = clorderlist.get(i); if(objectutil.isnotempty(clorder)){ date ordertime = clorder.getordertime(); long between = cn.hutool.core.date.dateutil.between(ordertime, new date(), dateunit.minute); if(between>10){ clorder clordertemp = new clorder(); clordertemp.setorderstate("3"); clordertemp.setid(clorder.getid()); clordertemp.setmemberid(clorder.getmemberid()); string msg="您的订单已经取消,订单金额已发放至您的账户请查收~"; try { boolean b = orderservice.cancelorder(clordertemp,msg); if(!b){ log.info("[订单失效:定时任务兜底策略更新失败]**订单id: {}",clordertemp.getid()); } log.info("[redis订单取消订单失效,定时任务兜底策略生效]"); }catch (exception e){ log.info("[订单失效:定时任务兜底策略更新失败]**订单id: {}",clordertemp.getid()); e.printstacktrace(); } } } } } log.info("*****[结束:下单十分钟以后系统自动取消订单]*****"); }
以上就是redis如何实现订单过期删除的详细内容。