缓存命中污染

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