feat: updateOrderStatus异步执行方法增加锁,等待异步方法执行完毕

This commit is contained in:
张松
2024-12-26 14:11:21 +08:00
parent 650b3bc4ea
commit ff86d3969b
3 changed files with 73 additions and 3 deletions

View File

@@ -1,15 +1,21 @@
package com.sqx.common.utils; package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date; import java.util.Date;
import java.util.UUID;
import java.util.function.Supplier;
/** /**
* 接口访问次数 月为单位 * 接口访问次数 月为单位
*/ */
@Component @Component
@Slf4j
public class ApiAccessLimitUtil { public class ApiAccessLimitUtil {
private static final String ACCESS_COUNT_KEY_PREFIX = "sys:limit:"; private static final String ACCESS_COUNT_KEY_PREFIX = "sys:limit:";
@@ -122,6 +128,48 @@ public class ApiAccessLimitUtil {
} }
public static<T> T runFunAndCheckKey(Supplier<T> supplier, String lockKey, Integer seconds) {
try{
// 创建线程id, 用作判断
String clientId = UUID.randomUUID().toString();
// 设置分布式锁
boolean lock = Boolean.TRUE.equals(redisUtils.setIfAbsent(lockKey, clientId, seconds));
int count = 0;
while (!lock) {
if (count++ > 100) {
throw new RuntimeException("系统繁忙, 稍后再试");
}
Thread.sleep(20);
lock = Boolean.TRUE.equals(redisUtils.setIfAbsent(lockKey, clientId, seconds));
}
return supplier.get();
} catch (RuntimeException e){
log.info("执行出错:{}", e.getMessage());
throw e;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally{
redisUtils.delete(lockKey);
}
}
public static boolean isAccessAllowed(String id, String key, Integer count, Integer seconds) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
redisUtils.set(redisKey, 1, seconds);
return true;
}
if (Integer.parseInt(countObj.toString()) < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
private static String generateRedisKey(String key, String id) { private static String generateRedisKey(String key, String id) {
return ACCESS_COUNT_KEY_PREFIX + key + ":" + id; return ACCESS_COUNT_KEY_PREFIX + key + ":" + id;
} }
@@ -142,4 +190,4 @@ public class ApiAccessLimitUtil {
long currentTimeStamp = DateUtil.currentSeconds(); long currentTimeStamp = DateUtil.currentSeconds();
return endTimeStamp - currentTimeStamp; return endTimeStamp - currentTimeStamp;
} }
} }

View File

@@ -9,6 +9,8 @@ import cn.hutool.core.date.DateUtil;
public class RedisKeys { public class RedisKeys {
public static final String FREE_WATCH_KEY = "free:watch:"; public static final String FREE_WATCH_KEY = "free:watch:";
public static final String LOCK_KEY = "SYS:LOCK:";
public static String getSysConfigKey(String key){ public static String getSysConfigKey(String key){
return "sys:config:" + key; return "sys:config:" + key;
@@ -28,4 +30,15 @@ public class RedisKeys {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println(DateUtil.today()); System.out.println(DateUtil.today());
} }
public static String getLockKey(String sign, Object... args) {
StringBuilder key = new StringBuilder(LOCK_KEY + ":" + sign + ":");
for (Object arg : args) {
if (arg != null) {
key.append(":").append(arg);
}
}
return key.toString();
}
} }

View File

@@ -4,7 +4,9 @@ import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.common.annotation.Debounce; import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.ApiAccessLimitUtil;
import com.sqx.common.utils.DateUtils; import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.RedisKeys;
import com.sqx.common.utils.Result; import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserEntity; import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoneyDetails; import com.sqx.modules.app.entity.UserMoneyDetails;
@@ -34,6 +36,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -68,12 +71,13 @@ public class WuyouController {
private final CashOutDao cashOutDao; private final CashOutDao cashOutDao;
private final CompletAwardService completAwardService; private final CompletAwardService completAwardService;
private final SysUserService sysUserService; private final SysUserService sysUserService;
private final ApplicationContext applicationContext;
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
WuyouController(OrdersService ordersService, PayDetailsDao payDetailsDao, UserService userService, InviteService inviteService, CashOutDao cashOutDao, WuyouController(OrdersService ordersService, PayDetailsDao payDetailsDao, UserService userService, InviteService inviteService, CashOutDao cashOutDao,
UserMoneyService userMoneyService, UserMoneyDetailsService userMoneyDetailsService, CommonInfoService commonRepository, UserMoneyService userMoneyService, UserMoneyDetailsService userMoneyDetailsService, CommonInfoService commonRepository,
InviteDao inviteDao,CompletAwardService completAwardService, SysUserService sysUserService) { InviteDao inviteDao, CompletAwardService completAwardService, SysUserService sysUserService, ApplicationContext applicationContext) {
this.ordersService = ordersService; this.ordersService = ordersService;
this.payDetailsDao = payDetailsDao; this.payDetailsDao = payDetailsDao;
this.userService = userService; this.userService = userService;
@@ -85,6 +89,7 @@ public class WuyouController {
this.inviteDao = inviteDao; this.inviteDao = inviteDao;
this.completAwardService = completAwardService; this.completAwardService = completAwardService;
this.sysUserService = sysUserService; this.sysUserService = sysUserService;
this.applicationContext = applicationContext;
} }
@Debounce(interval = 1000, value = "#orderId") @Debounce(interval = 1000, value = "#orderId")
@@ -335,7 +340,11 @@ public class WuyouController {
ordersService.updateById(order); ordersService.updateById(order);
ordersService.insertOrders(order); ordersService.insertOrders(order);
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
activities(user, byUser); ApiAccessLimitUtil.runFunAndCheckKey(() -> {
WuyouController proxy = applicationContext.getBean(WuyouController.class);
proxy.activities(user, byUser);
return null;
}, RedisKeys.getLockKey("activaties", user.getUserId(), byUser.getUserId()), 15);
}); });
} }