|
|
@@ -26,6 +26,8 @@ import com.google.gson.JsonParser;
|
|
|
import com.tencent.wework.Finance;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.json.JSONObject;
|
|
|
+import org.redisson.api.RLock;
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
@@ -73,6 +75,9 @@ public class QwDataCallbackService {
|
|
|
@Autowired
|
|
|
IQwAutoTagsService qwAutoTagsService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private RedissonClient redissonClient;
|
|
|
+
|
|
|
@Autowired
|
|
|
IQwAutoTagsLogsService qwAutoTagsLogsService;
|
|
|
|
|
|
@@ -202,13 +207,41 @@ public class QwDataCallbackService {
|
|
|
if(WelcomeCodeList.getLength() > 0) {
|
|
|
WelcomeCode = WelcomeCodeList.item(0).getTextContent();
|
|
|
}
|
|
|
-
|
|
|
- String qwApiExternal=redisCache.getCacheObject("qwApiExternal:"+root.getElementsByTagName("UserID").item(0).getTextContent()+":"+corpId+":"+root.getElementsByTagName("ExternalUserID").item(0).getTextContent());
|
|
|
- if (StringUtil.strIsNullOrEmpty(qwApiExternal)){
|
|
|
- redisCache.setCacheObject("qwApiExternal:"+root.getElementsByTagName("UserID").item(0).getTextContent()+":"+corpId+":"+root.getElementsByTagName("ExternalUserID").item(0).getTextContent() ,"1",10, TimeUnit.MINUTES);
|
|
|
- qwExternalContactService.insertQwExternalContactByExternalUserId(root.getElementsByTagName("ExternalUserID").item(0).getTextContent(),root.getElementsByTagName("UserID").item(0).getTextContent(),null,corpId,State,WelcomeCode);
|
|
|
-
|
|
|
+ String userId = root.getElementsByTagName("UserID").item(0).getTextContent();
|
|
|
+ String externalUserId = root.getElementsByTagName("ExternalUserID").item(0).getTextContent();
|
|
|
+ String cacheKey = "qwApiExternal:" + userId + ":" + corpId + ":" + externalUserId;
|
|
|
+ String lockKey = "lock:qwApiExternal:" + userId + ":" + corpId + ":" + externalUserId; // 锁Key(Hash类型,加前缀lock:)
|
|
|
+
|
|
|
+ // 2. 获取 Redisson 分布式锁
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+ boolean isLocked = false;
|
|
|
+ try {
|
|
|
+ // 3. 尝试加锁:最多等待 5 秒,锁自动释放时间 15 分钟
|
|
|
+ isLocked = lock.tryLock(5, 15, TimeUnit.MINUTES);
|
|
|
+ if (isLocked) {
|
|
|
+ // 4. 加锁成功后,再次检查缓存(避免多线程竞争时重复执行业务)
|
|
|
+ String qwApiExternal = redisCache.getCacheObject(cacheKey);
|
|
|
+ if (StringUtil.strIsNullOrEmpty(qwApiExternal)) {
|
|
|
+ try {
|
|
|
+ // 5. 新增用户
|
|
|
+ qwExternalContactService.insertQwExternalContactByExternalUserId(root.getElementsByTagName("ExternalUserID").item(0).getTextContent(),root.getElementsByTagName("UserID").item(0).getTextContent(),null,corpId,State,WelcomeCode);
|
|
|
+ // 6. 业务逻辑执行成功后,写入 Redis 缓存(有效期 10 分钟)
|
|
|
+ redisCache.setCacheObject(cacheKey, "1", 10, TimeUnit.MINUTES);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 7. 业务逻辑失败时,删除缓存
|
|
|
+ redisCache.deleteObject(cacheKey);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ logger.error("中断异常");
|
|
|
+ } finally {
|
|
|
+ // 4. 确保锁最终被释放(只有加锁成功的线程才需要释放)
|
|
|
+ if (isLocked && lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
case "edit_external_contact":
|
|
|
qwExternalContactService.updateQwExternalContactByExternalUserId(root.getElementsByTagName("ExternalUserID").item(0).getTextContent(),root.getElementsByTagName("UserID").item(0).getTextContent(),corpId);
|