|
@@ -1,5 +1,6 @@
|
|
|
package com.sf.service;
|
|
|
|
|
|
+import com.sf.utils.DateUtils;
|
|
|
import com.sf.utils.RedisUtils;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
@@ -11,6 +12,8 @@ import org.springframework.data.redis.core.script.DefaultRedisScript;
|
|
|
import org.springframework.scripting.support.ResourceScriptSource;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
|
|
@@ -26,17 +29,41 @@ public class RedisServiceImpl implements RedisService {
|
|
|
// 先判断 是否在秒杀有效时间内
|
|
|
// 也就是当前时间 是否 >= startTime <= endTime
|
|
|
|
|
|
+ String keyStart = "1_startTime";
|
|
|
+ String keyEnd = "1_endTime";
|
|
|
+ String startStr = (String) redisUtils.get(keyStart);
|
|
|
+ String endStr = (String) redisUtils.get(keyEnd);
|
|
|
+
|
|
|
+ LocalDateTime startTime = DateUtils.getDateTime(startStr);
|
|
|
+ LocalDateTime endTime = DateUtils.getDateTime(endStr);
|
|
|
+ LocalDateTime nowTime = LocalDateTime.now();
|
|
|
+
|
|
|
+ if (nowTime.isBefore(startTime)) {
|
|
|
+ log.info("还未到秒杀开始时间");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (nowTime.isAfter(endTime)) {
|
|
|
+ log.info("秒杀已结束");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ log.info("正在进行秒杀");
|
|
|
+
|
|
|
// goodsId = 1
|
|
|
// 1_stock_num
|
|
|
-// String key = goodsId + "_stock_num";
|
|
|
-// Integer num = (Integer) redisUtils.get(key);
|
|
|
-// // 出现超卖的原因
|
|
|
-// // 当10个线程同时获取num的值 此时num=5 会同时进行自减操作
|
|
|
-// if (num > 0) {
|
|
|
-// Long decr = redisUtils.decr(key);
|
|
|
-// System.out.println(decr);
|
|
|
-// }
|
|
|
// handleByTran(userId, goodsId);
|
|
|
+
|
|
|
+
|
|
|
+ // 双重校验的机制
|
|
|
+ // 先验证是否有库存
|
|
|
+ String key = goodsId + "_stock_num";
|
|
|
+ Integer num = (Integer) redisUtils.get(key);
|
|
|
+ // 出现超卖的原因
|
|
|
+ // 当10个线程同时获取num的值 此时num=5 会同时进行自减操作
|
|
|
+ if (num == 0) {
|
|
|
+ log.info("已经秒杀光了");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 在执行脚本之后 再一次验证有库存
|
|
|
handleByLua(userId, goodsId);
|
|
|
|
|
|
// 加锁 乐观锁和悲观锁
|
|
@@ -107,6 +134,19 @@ public class RedisServiceImpl implements RedisService {
|
|
|
|
|
|
@Override
|
|
|
public void init() {
|
|
|
+ // 初始化时增加秒杀开始和结束时间
|
|
|
+ // <1_startTime,"20220224">
|
|
|
+ // <1_endTime,"20220227">
|
|
|
+
|
|
|
+ String startTime = DateUtils.getDateTimeStr(2024, 2, 22);
|
|
|
+ String endTime = DateUtils.getDateTimeStr(2024, 2, 24);
|
|
|
+
|
|
|
+ String keyStart = "1_startTime";
|
|
|
+ String keyEnd = "1_endTime";
|
|
|
+
|
|
|
+ redisUtils.set(keyStart, startTime);
|
|
|
+ redisUtils.set(keyEnd, endTime);
|
|
|
+
|
|
|
// 初始化秒杀商品的库存数量
|
|
|
// stockNum
|
|
|
// <1,10> <1,9>
|
|
@@ -124,9 +164,5 @@ public class RedisServiceImpl implements RedisService {
|
|
|
// map.put("2", 10L);
|
|
|
// redisUtils.setAllMap("stock_num", map);
|
|
|
|
|
|
-
|
|
|
- // <1_startTime,"20220224">
|
|
|
- // <1_endTime,"20220227">
|
|
|
-
|
|
|
}
|
|
|
}
|