|
|
@@ -187,14 +187,6 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
|
|
|
return R.error("您已经领取过红包了!");
|
|
|
}
|
|
|
/*try {*/
|
|
|
- Integer remaining = getRemaining(red.getRedId());
|
|
|
- if (remaining <= 0) {
|
|
|
- LiveRedConf liveRedConf = new LiveRedConf();
|
|
|
- liveRedConf.setRedId(red.getRedId());
|
|
|
- liveRedConf.setRedStatus(2L);
|
|
|
- baseMapper.updateLiveRedConf(liveRedConf);
|
|
|
- return R.error("手慢了,红包已被抢完~");
|
|
|
- }
|
|
|
/* //获取红包锁
|
|
|
if (!tryLock(claimKey, red.getUserId().toString(), 5)) {
|
|
|
return R.error("您已经领取过红包了!");
|
|
|
@@ -202,13 +194,13 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
|
|
|
|
|
|
LiveRedConf conf = baseMapper.selectLiveRedConfByRedId(red.getRedId());
|
|
|
if (conf == null || conf.getRedStatus() != 1) {
|
|
|
- return R.error("手慢了,红包已被抢完~");
|
|
|
+ return R.error("手慢了,红包已结束~");
|
|
|
}
|
|
|
//redis剩余红包数
|
|
|
// 平均分 暂时不适用redis 记录红包数
|
|
|
Long integral = calculateIntegralAverage(conf);
|
|
|
if (0L == integral) {
|
|
|
- return R.error("手慢了,红包已被抢完~");
|
|
|
+ return R.error("手慢了,红包被抢完了~");
|
|
|
}
|
|
|
|
|
|
// 更新数据库
|
|
|
@@ -220,6 +212,16 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
|
|
|
baseMapper.updateLiveRedConf(conf);
|
|
|
*/
|
|
|
|
|
|
+ // 最后更新缓存
|
|
|
+ if (getRemaining(red.getRedId()) <= 0 || !decreaseRemainingLotsIfPossible(red.getRedId())) {
|
|
|
+ LiveRedConf liveRedConf = new LiveRedConf();
|
|
|
+ liveRedConf.setRedId(red.getRedId());
|
|
|
+ liveRedConf.setRedStatus(2L);
|
|
|
+ baseMapper.updateLiveRedConf(liveRedConf);
|
|
|
+ Set<String> range = CollUtil.newHashSet(String.valueOf(red.getRedId()));
|
|
|
+ finishRedStatusBySetIds(range);
|
|
|
+ return R.error("手慢了,红包已被抢完~");
|
|
|
+ }
|
|
|
// 记录用户红包
|
|
|
LiveUserRedRecord record = new LiveUserRedRecord();
|
|
|
record.setRedId(red.getRedId());
|
|
|
@@ -227,10 +229,6 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
|
|
|
record.setUserId(red.getUserId());
|
|
|
record.setIntegral(integral);
|
|
|
record.setCreateTime(new Date());
|
|
|
- // userRedRecordMapper.insertLiveUserRedRecord(record);
|
|
|
-
|
|
|
- // 最后更新缓存
|
|
|
- decreaseRemainingLotsIfPossible(red.getRedId());
|
|
|
// WebSocket 通知
|
|
|
//String msg = String.format("用户 %d 抢到了红包 %d,获得 %d 芳华币", userId, redId, integral);
|
|
|
//WebSocketServer.notifyUsers(msg);
|
|
|
@@ -275,12 +273,7 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
|
|
|
for (String s : range) {
|
|
|
LiveRedConf liveRedConf = baseMapper.selectLiveRedConfByRedId(Long.valueOf(s));
|
|
|
// 更新数据库
|
|
|
- Date now = new Date();
|
|
|
- Integer remaining = getRemaining(liveRedConf.getRedId());
|
|
|
- liveRedConf.setTotalSend(liveRedConf.getTotalLots() - remaining);
|
|
|
- liveRedConf.setRemaining(remaining);
|
|
|
- liveRedConf.setUpdateTime(now);
|
|
|
- baseMapper.updateLiveRedConf(liveRedConf);
|
|
|
+ updateDbByRed(liveRedConf);
|
|
|
String hashKey = String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_RED, liveRedConf.getLiveId(), liveRedConf.getRedId());
|
|
|
Map<Object, Object> hashEntries = redisUtil.hashEntries(hashKey);
|
|
|
List<LiveUserRedRecord> liveUserRedRecords = new ArrayList<>();
|
|
|
@@ -308,17 +301,22 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
|
|
|
liveRedConf.setRedStatus(1L);
|
|
|
List<LiveRedConf> conf = baseMapper.selectLiveRedConfList(liveRedConf);
|
|
|
for (LiveRedConf red : conf) {
|
|
|
- // 更新数据库
|
|
|
- Date now = new Date();
|
|
|
- Integer remaining = getRemaining(red.getRedId());
|
|
|
- red.setTotalSend(red.getTotalLots() - remaining);
|
|
|
- red.setRemaining(remaining);
|
|
|
- red.setUpdateTime(now);
|
|
|
- baseMapper.updateLiveRedConf(red);
|
|
|
- log.info("更新红包数据完成 {} {}",red.getRedId(),remaining);
|
|
|
+ updateDbByRed(red);
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void updateDbByRed(LiveRedConf red) {
|
|
|
+ // 更新数据库
|
|
|
+ Date now = new Date();
|
|
|
+ Integer remaining = getRemaining(red.getRedId());
|
|
|
+ red.setTotalSend(red.getTotalLots() - remaining);
|
|
|
+ red.setRemaining(remaining);
|
|
|
+ red.setUpdateTime(now);
|
|
|
+ baseMapper.updateLiveRedConf(red);
|
|
|
+ log.info("更新红包数据完成 {} {}",red.getRedId(),remaining);
|
|
|
+ }
|
|
|
+
|
|
|
// 初始化剩余数量
|
|
|
public void initRemainingLots(Long redId, Integer totalLots) {
|
|
|
String key = REDPACKET_REMAININGLOTS_KEY + redId;
|
|
|
@@ -349,9 +347,20 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
|
|
|
}
|
|
|
|
|
|
// 减少剩余数量(原子操作)
|
|
|
- public void decreaseRemainingLotsIfPossible(Long redId) {
|
|
|
+ public boolean decreaseRemainingLotsIfPossible(Long redId) {
|
|
|
String key = REDPACKET_REMAININGLOTS_KEY + redId;
|
|
|
- redisCache.incrementCacheValue(key, -1);
|
|
|
+ // 通过lua脚本校验剩余数量是否大于0
|
|
|
+ String script = "local current = redis.call('GET', KEYS[1]) " +
|
|
|
+ "if current and tonumber(current) > 0 then " +
|
|
|
+ " return redis.call('DECRBY', KEYS[1], 1) " +
|
|
|
+ "else " +
|
|
|
+ " return -1 " +
|
|
|
+ "end";
|
|
|
+ DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
|
|
|
+ redisScript.setScriptText(script);
|
|
|
+ redisScript.setResultType(Long.class);
|
|
|
+ Object result = redisCache.redisTemplate.execute(redisScript, Collections.singletonList(key));
|
|
|
+ return result != null && Long.valueOf(result.toString()) >= 0;
|
|
|
}
|
|
|
// 减少剩余数量(原子操作)
|
|
|
public void decreaseRemainingNumIfPossible(Long redId, Long integral) {
|