如何避免Spring服务中Redis缓存的TTL被自动续期?
Redis缓存TTL自动续期问题排查
问题背景
我正在排查一个Spring服务的Bug:该服务用Redis缓存查询结果,要求缓存时长30分钟,TTL仅在首次存入缓存时设置,后续查询不得续期——这本来是原生Redis的默认行为,但实际运行中每次调用缓存都会续期TTL。奇怪的是项目里Redis相关配置极少,却未按预期工作。
当前Redis配置
POJO注解配置
唯一的Redis代码配置是在被缓存的POJO上添加了@RedisHash注解:
@RedisHash(value = "POJO_NAME", timeToLive = 1800)
application.yml配置
redis: service: name: project-cache host: localhost port: 6379 jedis: pool: max-total: 16 max-idle: 8 min-idle: 4 timeout: 250
项目依赖(pom.xml)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <dependency> <groupId>it.ozimov</groupId> <artifactId>embedded-redis</artifactId> <version>0.7.2</version> <scope>test</scope> <exclusions> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </exclusion> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </exclusion> </exclusions> </dependency>
问题根源分析
问题出在@RedisHash注解的使用逻辑上:这个注解属于Spring Data Redis的Repository模式范畴,并非通用的Spring Cache抽象。当通过Spring Data Redis的Repository接口查询实体时,框架默认会在每次加载实体后自动刷新TTL,这是该模式的内置行为,和原生Redis GET操作不续期的逻辑完全不同。
解决方案建议
- 切换为Spring Cache抽象:如果要实现“首次设置TTL,查询不续期”的需求,推荐使用Spring Cache的
@Cacheable注解,配合自定义RedisCacheManager配置TTL。这种方式更贴合通用缓存场景的预期行为。 - 修改Repository行为:若必须继续使用Spring Data Redis Repository模式,需要自定义RedisKeyValueAdapter或修改RedisMappingContext的配置,禁用查询时的TTL自动刷新逻辑。比如重写
afterLoad方法,避免更新实体的过期时间。
内容的提问来源于stack exchange,提问作者dbrewster
相关产品推荐
相关产品推荐

