缓存命中污染

This commit is contained in:
2026-08-17 09:21:56 +08:00
parent 397e89d723
commit 58cb64814f
2 changed files with 39 additions and 11 deletions
@@ -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);
}
}