Spring Boot无参数接口缓存:新增客户时自动更新缓存方案咨询
解决方案
1. 主动触发缓存更新(最优方案)
在客户新增的业务逻辑里,直接联动更新缓存——要么清除现有缓存,要么直接替换缓存内容。这样下次请求GET /customers时,会自动从数据库拉取最新列表并重新缓存。
以Spring Cache为例,代码实现如下:
@Service public class CustomerService { // 新增客户时,清除customers缓存 @CacheEvict(value = "customers", allEntries = true) public void addCustomer(Customer customer) { customerRepository.save(customer); } // 查询客户列表时,优先返回缓存;缓存不存在则查库并缓存 @Cacheable(value = "customers") public List<Customer> getCustomers() { return customerRepository.findAll(); } }
每次新增客户后,缓存会被清空,下一次查询请求就会自动触发数据库查询并更新缓存,完全不需要额外请求校验。
2. 版本号校验缓存(适合低更新频率场景)
给客户列表维护一个全局版本号,缓存时同时存储版本号和列表数据。每次查询接口先校验版本号,只有版本号变化时才更新缓存。
步骤实现:
- 用Redis或数据库存储版本号(比如键为
customer_list_version,初始值0) - 新增客户时,版本号自增:
public void addCustomer(Customer customer) { customerRepository.save(customer); redisTemplate.opsForValue().increment("customer_list_version"); }
- 查询客户列表时校验版本号:
public List<Customer> getCustomers() { Long currentVersion = redisTemplate.opsForValue().get("customer_list_version"); Cache.ValueWrapper cacheWrapper = cacheManager.getCache("customers").get("customer_data"); if (cacheWrapper != null) { Map<String, Object> cacheData = (Map<String, Object>) cacheWrapper.get(); Long cachedVersion = (Long) cacheData.get("version"); if (currentVersion.equals(cachedVersion)) { return (List<Customer>) cacheData.get("list"); } } // 版本不一致,重新查库并更新缓存 List<Customer> latestList = customerRepository.findAll(); Map<String, Object> newCacheData = new HashMap<>(); newCacheData.put("version", currentVersion); newCacheData.put("list", latestList); cacheManager.getCache("customers").put("customer_data", newCacheData); return latestList; }
这种方式一次请求就能完成校验和缓存更新,不会增加额外请求次数,适合更新频率低的场景。
3. 定时刷新缓存(兜底方案)
如果担心主动更新逻辑存在遗漏(比如批量导入客户时未触发缓存更新),可以搭配定时任务定期刷新缓存,时间间隔根据业务调整(比如1小时):
@Scheduled(fixedRate = 3600000) // 每1小时执行一次 @CacheEvict(value = "customers", allEntries = true) public void refreshCustomerCache() { // 清空缓存,下次请求自动加载最新数据 }
可以将此作为主动更新的补充,避免极端场景下的缓存不一致问题。
内容的提问来源于stack exchange,提问作者fckNewbee
相关产品推荐
相关产品推荐

