Pre Merge pull request !1094 from 牛亚博/防重提交添加分布式锁,处理真正的并发场景
commit
b55298852c
|
|
@ -65,23 +65,37 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
|
||||||
// 唯一标识(指定key + url + 消息头)
|
// 唯一标识(指定key + url + 消息头)
|
||||||
String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey;
|
String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey;
|
||||||
|
|
||||||
Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
|
// 使用原子操作检查并设置,避免竞态条件
|
||||||
if (sessionObj != null)
|
String lockKey = cacheRepeatKey + "_lock";
|
||||||
{
|
|
||||||
Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
|
// 先尝试获取分布式锁,防止并发问题
|
||||||
if (sessionMap.containsKey(url))
|
Boolean lockResult = redisCache.redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 1, TimeUnit.SECONDS);
|
||||||
{
|
if (lockResult == null || !lockResult) {
|
||||||
Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
|
// 获取锁失败,说明有并发请求,直接返回重复提交
|
||||||
if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval()))
|
return true;
|
||||||
{
|
}
|
||||||
return true;
|
|
||||||
|
try {
|
||||||
|
Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
|
||||||
|
|
||||||
|
if (sessionObj != null) {
|
||||||
|
Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
|
||||||
|
if (sessionMap.containsKey(url)) {
|
||||||
|
Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
|
||||||
|
if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, Object> cacheMap = new HashMap<String, Object>();
|
||||||
|
cacheMap.put(url, nowDataMap);
|
||||||
|
redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
// 释放锁
|
||||||
|
redisCache.deleteObject(lockKey);
|
||||||
}
|
}
|
||||||
Map<String, Object> cacheMap = new HashMap<String, Object>();
|
|
||||||
cacheMap.put(url, nowDataMap);
|
|
||||||
redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue