網(wǎng)站首頁 編程語言 正文
前言
設(shè)計(jì)訂單過期,不能單純靠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);
? ? ? ? ? ? ? ? //如果最小的都沒有過期,剩余的則不用處理了
? ? ? ? ? ? ? ? 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("*****[開始:下單十分鐘以后系統(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)取消訂單]*****");
? ? }
原文鏈接:https://blog.csdn.net/qq_32370913/article/details/124773954
相關(guān)推薦
- 2022-07-19 Docker容器內(nèi)存占用過高解決方法
- 2023-01-30 delphi?判斷字符串是否包含漢字,正則版與非正則版實(shí)現(xiàn)_Delphi
- 2022-04-28 C#操作進(jìn)程的方法介紹_C#教程
- 2022-03-14 sql 排序order by重復(fù)數(shù)據(jù)問題
- 2022-04-23 uni-app之項(xiàng)目首頁實(shí)現(xiàn)步驟
- 2023-02-06 Python實(shí)現(xiàn)號(hào)碼歸屬地查詢功能_python
- 2022-08-22 PyCharm安裝庫(kù)numpy失敗問題的詳細(xì)解決方法_python
- 2022-07-06 python數(shù)據(jù)挖掘Apriori算法實(shí)現(xiàn)關(guān)聯(lián)分析_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支