feat: updateOrderStatus异步执行方法增加锁,等待异步方法执行完毕
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user