Redis實(shí)現(xiàn)訂單過(guò)期刪除的方法步驟
前言
設(shè)計(jì)訂單過(guò)期,不能單純靠Redis,需要兜底策略
代碼實(shí)現(xiàn):
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
@Slf4j
public class OrderRedisDelayQueueOperator extends AbstractOrderScheduleDelayQueue {
? ? @Resource(name = "redisTemplate")
? ? private ZSetOperations<String, String> orderRedis;
? ? /**
? ? ?* 預(yù)售、現(xiàn)貨生成訂單15分鐘后未支付,需要取消訂單
? ? ?*/
? ? private static final String DELAY_QUEUE_NAME = "order";
? ? /**
? ? ?* 每1秒執(zhí)行一次
? ? ?*/
? ? @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);
? ? ? ? ? ? ? ? //如果最小的都沒(méi)有過(guò)期,剩余的則不用處理了
? ? ? ? ? ? ? ? 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分鐘執(zhí)行一次
? ? ?*/
? ? @XxlJob("cancelOrder20Minutes")
? ? public void cancelOrderTenMinutes() {
? ? ? ? log.info("*****[開(kāi)始:下單十分鐘以后系統(tǒng)自動(dòng)取消訂單]*****");
? ? ? ? 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="您的訂單已經(jīng)取消,訂單金額已發(fā)放至您的賬戶請(qǐng)查收~";
? ? ? ? ? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ? ? ? ? ?boolean b = orderService.cancelOrder(clOrderTemp,msg);
? ? ? ? ? ? ? ? ? ? ? ? ? ?if(!b){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?log.info("[訂單失效:定時(shí)任務(wù)兜底策略更新失敗]**訂單ID: {}",clOrderTemp.getId());
? ? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ? ?log.info("[Redis訂單取消訂單失效,定時(shí)任務(wù)兜底策略生效]");
? ? ? ? ? ? ? ? ? ? ? ?}catch (Exception e){
? ? ? ? ? ? ? ? ? ? ? ? ? ?log.info("[訂單失效:定時(shí)任務(wù)兜底策略更新失敗]**訂單ID: {}",clOrderTemp.getId());
? ? ? ? ? ? ? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?}
? ? ? ? log.info("*****[結(jié)束:下單十分鐘以后系統(tǒng)自動(dòng)取消訂單]*****");
? ? }
到此這篇關(guān)于Redis實(shí)現(xiàn)訂單過(guò)期刪除的方法步驟的文章就介紹到這了,更多相關(guān)Redis 訂單過(guò)期刪除內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis Key的數(shù)量上限及優(yōu)化策略分享
Redis 作為高性能的鍵值存儲(chǔ)數(shù)據(jù)庫(kù),廣泛應(yīng)用于緩存、會(huì)話存儲(chǔ)、排行榜等場(chǎng)景,但在實(shí)際使用中,開(kāi)發(fā)者常常會(huì)關(guān)心一個(gè)問(wèn)題:Redis 的 Key 數(shù)量是否有上限?本文將從 Redis Key 的理論上限 出發(fā),深入探討 Redis Key 的管理策略,需要的朋友可以參考下2025-03-03
kubernetes環(huán)境部署單節(jié)點(diǎn)redis數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了kubernetes環(huán)境部署單節(jié)點(diǎn)redis數(shù)據(jù)庫(kù)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
redis 存儲(chǔ)對(duì)象的方法對(duì)比分析
這篇文章主要介紹了redis 存儲(chǔ)對(duì)象的方法對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
基于Redis實(shí)現(xiàn)阻塞隊(duì)列的方式
本文主要講解基于?Redis?的方式實(shí)現(xiàn)異步隊(duì)列,基于?Redis?的?list?實(shí)現(xiàn)隊(duì)列的方式也有多種,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2021-12-12
Redisson延時(shí)隊(duì)列RedissonDelayed的具體使用
詳解Centos7下配置Redis并開(kāi)機(jī)自啟動(dòng)

