1. 程式人生 > >Redis有序集合和定時任務解決訂單15分鐘關閉

Redis有序集合和定時任務解決訂單15分鐘關閉

直接上程式碼

   下單減去庫存

    public String updatePersonStock(PageData pd) throws Exception {
Map<String, Object> resmap = new HashMap<>();
int result = dao.updateReturnInt("PersonstockMapper.updatePersonStock", pd);
if (result == 1) {
// 返回下單成功
logger.info("搶購成功" + pd);
resmap.put("code", "10000");
resmap.put("message", "搶購成功");
zset = redisTemplate.opsForZSet();
long orderId = Long.valueOf(String.valueOf(pd.get("orderId")));
long time = System.currentTimeMillis()+900000;
zset.add(Const.KEY, orderId, time);
return FastJsonUtils.toJSONString(resmap);
} else {
dao.updateReturnInt("PersonstockMapper.updateAddStock", pd);
logger.info("購買數量大於商品限制購買數量" + pd);
// 返回下單失敗
resmap.put("code", "10613");
resmap.put("message", "購買數量大於商品限制購買數量");
return FastJsonUtils.toJSONString(resmap);
}

}

       public final static String KEY = "csh_timeoutpromotionorderset";   

         /**

* 隨機生成 雪花演算法
*/
public final static long ORDERID = 25312144988416020l;
/**
* 設定一個 比較大的值
*/

public final static long SCORE = 9999999999999L;

//處理訂單超時 15分鐘呼叫一次

public void dealPromotionOrderTimeout() throws Exception {
zset = redisTemplate.opsForZSet();
Double result = zset.score(Const.KEY, Const.ORDERID);
//result為空 表示key未建立 或key值 丟失過 
if (result == null) {
// 先取消,呼叫方法全表掃描
orderService.dealPromotionOrderTimeout();
// 再新增
zset.add(Const.KEY, Const.ORDERID, Const.SCORE);
cancelPromotionOrder(Const.KEY);
}else{
cancelPromotionOrder(Const.KEY);
}

}

public void cancelPromotionOrder(String key) throws InterruptedException  {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
long time = System.currentTimeMillis()+900000;
while (System.currentTimeMillis()<time) {
Set<TypedTuple<Object>> itemSet = zset.rangeWithScores(key, 0, 0);
if (itemSet == null || itemSet.isEmpty()) {
Thread.sleep(1000);
continue;
}else{
double score = ((TypedTuple<Object>) itemSet.toArray()[0]).getScore();
if(score == Const.SCORE){
Thread.sleep(1000);
continue;
}
}
double score = ((TypedTuple<Object>) itemSet.toArray()[0]).getScore(); // 超時時間搓
double currentTime = System.currentTimeMillis();
if (currentTime >= score) {
long element = ((TypedTuple<Long>) itemSet.toArray()[0]).getValue(); // orderID
PageData pd = new PageData();
pd.put("ordesstatus", "X");
pd.put("ordersid", element);
pd.put("key", key);
pd.put("element", element);
/**
* 1 是訂單已經取消失敗DuplicateKeyException
* 0 是取消成功
* 2 是訂單已經取消
*/
int result = orderService.buttonCancalOrderRedis(pd);
if(result == 0){
logger.info( " redis 處理了一個訂單取消任務 score:" + score + ", member:" + element);
zset.remove(key, element);
}else if(result == 1){
zset.remove(key, element);
}else if(result == 2){
zset.remove(key, element);
}else{
logger.error( "伺服器異常");
}

}
}
}