網站首頁 編程語言 正文
前言
設計訂單過期,不能單純靠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
@Slf4j
public 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("*****[結束:下單十分鐘以后系統自動取消訂單]*****");
? ? }
原文鏈接:https://blog.csdn.net/qq_32370913/article/details/124773954
相關推薦
- 2023-12-15 Linux系統——退出vi編輯模式
- 2022-04-21 Android自定義View實現標簽流效果_Android
- 2022-10-31 Golang?template?包基本原理分析_Golang
- 2022-03-30 Android用動畫顯示或隱藏視圖_Android
- 2022-07-07 Python推導式使用詳情_python
- 2022-06-01 C++程序內存棧區與堆區模型案例分析_C 語言
- 2022-06-12 PostgreSQL數據庫事務插入刪除及更新操作示例_PostgreSQL
- 2023-07-02 解密Python中的作用域與名字空間_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支