缓存命中污染
This commit is contained in:
+16
-3
@@ -41,17 +41,30 @@ public class BaseSchsystemGradeService implements IBaseSchsystemGradeService {
|
||||
|
||||
String cacheKey = RedisConstants.SCHOOL_GRAGE+"_"+schId;
|
||||
|
||||
if (redisUtil.hasKey(cacheKey))
|
||||
return redisUtil.getList(cacheKey,BaseSchsystemGrade.class);
|
||||
// 空结果(null 或 空列表)视为未命中,回源 DB,避免空缓存长期毒化
|
||||
List<BaseSchsystemGrade> cached = redisUtil.getList(cacheKey, BaseSchsystemGrade.class);
|
||||
if (cached != null && !cached.isEmpty()) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
List<Integer> schsystemIds= schBinSchsystemService.getSchBinSchsystemIds(schId);
|
||||
|
||||
List<BaseSchsystemGrade> list=baseSchsystemGradeRepository.findBySchSystemIdIn(schsystemIds);
|
||||
|
||||
redisUtil.set(cacheKey, list , RedisConstants.CACHE_EXPIRE_30D);
|
||||
// 仅缓存非空结果
|
||||
if (!list.isEmpty()) {
|
||||
redisUtil.set(cacheKey, list , RedisConstants.CACHE_EXPIRE_30D);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 学校学制年级数据变更后调用:清除指定学校的学制年级缓存
|
||||
*/
|
||||
public void clearSchGradeCache(Integer schId) {
|
||||
redisUtil.del(RedisConstants.SCHOOL_GRAGE + "_" + schId);
|
||||
}
|
||||
|
||||
|
||||
public List<BaseSchsystemGrade> getSchGradeCacheList(Integer schId,Integer schsystemId,Integer gradeId) {
|
||||
List<BaseSchsystemGrade> list = getSchGradeCacheList(schId);
|
||||
|
||||
@@ -27,21 +27,36 @@ public class BaseSchsystemService implements IBaseSchsystemService {
|
||||
public List<BaseSchsystem> getSchsystemList() {
|
||||
String cacheKey = RedisConstants.SYSTEM_SCHSYSTEM;
|
||||
|
||||
if (redisUtil.hasKey(cacheKey))
|
||||
return redisUtil.getList(cacheKey,BaseSchsystem.class);
|
||||
// 1. 先读缓存;空结果(null 或 空列表)视为未命中,强制回源 DB,
|
||||
// 避免“冷启动时把 [] 写进缓存后长期毒化”的问题
|
||||
List<BaseSchsystem> cached = redisUtil.getList(cacheKey, BaseSchsystem.class);
|
||||
if (cached != null && !cached.isEmpty()) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
//加锁防止缓存击穿
|
||||
// 2. 加锁防止缓存击穿 + 双重检查
|
||||
synchronized (this) {
|
||||
// 双重检查
|
||||
if (redisUtil.hasKey(cacheKey))
|
||||
return redisUtil.getList(cacheKey,BaseSchsystem.class);
|
||||
cached = redisUtil.getList(cacheKey, BaseSchsystem.class);
|
||||
if (cached != null && !cached.isEmpty()) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
// 3. 从数据库查询
|
||||
List<BaseSchsystem> list = baseSchSystemRepository.findAll();
|
||||
// 4. 存入缓存(即使是空列表也缓存,避免穿透)
|
||||
redisUtil.set(cacheKey, list, RedisConstants.CACHE_EXPIRE_30D);
|
||||
|
||||
// 4. 仅缓存非空结果;空结果不缓存,防止空缓存污染(穿透风险可忽略)
|
||||
if (!list.isEmpty()) {
|
||||
redisUtil.set(cacheKey, list, RedisConstants.CACHE_EXPIRE_30D);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 学制数据变更后调用:清除学制列表缓存(base_sch_system 写入/更新/删除时触发)
|
||||
*/
|
||||
public void clearSchsystemCache() {
|
||||
redisUtil.del(RedisConstants.SYSTEM_SCHSYSTEM);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user