From 6a4f5e460ecd4a4b000e991f09393d8b360cc081 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 26 Jun 2026 10:03:39 +0800 Subject: [PATCH] =?UTF-8?q?fix(cache):=20=E5=85=AC=E5=85=B1=20set(key,null?= =?UTF-8?q?)=20=E6=94=B9=E7=94=A8=E7=9F=AD=20null-ttl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit set(key,null) 原按数据 TTL(可达 default-ttl-seconds)写入空值标记,使空标记长期 占位;改为与回源空值一致用 null-ttl-seconds(不抖动),空标记宜短。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../cache/template/RedisCacheEnhanceTemplate.java | 5 +++-- .../cache/template/RedisCacheEnhanceTemplateTest.java | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/njcn/middle/cache/template/RedisCacheEnhanceTemplate.java b/src/main/java/com/njcn/middle/cache/template/RedisCacheEnhanceTemplate.java index b6f42fa..07ba6a5 100644 --- a/src/main/java/com/njcn/middle/cache/template/RedisCacheEnhanceTemplate.java +++ b/src/main/java/com/njcn/middle/cache/template/RedisCacheEnhanceTemplate.java @@ -53,8 +53,9 @@ public class RedisCacheEnhanceTemplate { public void set(String key, Object value, long ttlSeconds) { requirePositiveTtl(ttlSeconds); - redis.opsForValue().set(keyBuilder.build(key), codec.encode(value), - applyJitter(ttlSeconds), TimeUnit.SECONDS); + // 空值(写入空标记)按短 null-ttl 处理,与回源 null 一致,避免空标记长期占位 + long ttl = (value == null) ? props.getNullTtlSeconds() : applyJitter(ttlSeconds); + redis.opsForValue().set(keyBuilder.build(key), codec.encode(value), ttl, TimeUnit.SECONDS); } // ---- 读 ---- diff --git a/src/test/java/com/njcn/middle/cache/template/RedisCacheEnhanceTemplateTest.java b/src/test/java/com/njcn/middle/cache/template/RedisCacheEnhanceTemplateTest.java index 6f4ab8c..093293e 100644 --- a/src/test/java/com/njcn/middle/cache/template/RedisCacheEnhanceTemplateTest.java +++ b/src/test/java/com/njcn/middle/cache/template/RedisCacheEnhanceTemplateTest.java @@ -339,4 +339,14 @@ class RedisCacheEnhanceTemplateTest { when(valueOps.get("cache:user:1")).thenReturn(null); assertFalse(template.exists("user:1")); } + + // ---- #9: 公共 set(key,null) 用短 null-ttl(与回源空值一致) ---- + + @Test + void setNullUsesNullTtlNotDataTtl() { + props.setJitterRatio(0); + template.set("user:1", null, 3600); // 传入数据 TTL,但写空标记应改用短 null-ttl + verify(valueOps).set("cache:user:1", CacheConstant.NULL_SENTINEL, + props.getNullTtlSeconds(), TimeUnit.SECONDS); + } }