如何判断Redis缓存是否过期并实现条件触发的数据库表更新
实现方案
核心逻辑梳理
先明确整个流程的触发条件与执行规则:
- 用户选中特定账户时,先原子更新该账户在统计Map中的访问次数
- 仅当访问次数大于1时,才进入Redis缓存检查环节
- 若缓存已过期(或不存在):执行数据库表的日期更新,同时重新加载最新数据到Redis并设置新过期时间
- 若缓存未过期:直接跳过数据库更新,继续使用缓存数据
关键代码实现(以Java为例)
以下是基于常见技术栈的落地代码,可根据你使用的语言/框架调整:
1. 访问次数统计与触发判断
使用线程安全的Map来保证多场景下计数准确:
// 线程安全的账户访问次数统计Map private final ConcurrentHashMap<String, Integer> accountVisitCount = new ConcurrentHashMap<>(); // 用户选中账户时调用此方法 public void handleAccountSelection(String accountId) { // 原子更新访问次数:首次访问设为1,后续每次+1 int currentCount = accountVisitCount.merge(accountId, 1, Integer::sum); // 仅当访问次数>1时,触发缓存检查与数据库更新逻辑 if (currentCount > 1) { checkCacheExpirationAndUpdateDb(accountId); } }
2. Redis缓存过期检查
通过Redis客户端获取缓存的剩余过期时间,判断是否需要更新数据库(这里以Redisson为例):
@Autowired private RedissonClient redissonClient; private void checkCacheExpirationAndUpdateDb(String accountId) { String cacheKey = "account:detail:" + accountId; RBucket<Object> cacheBucket = redissonClient.getBucket(cacheKey); // 获取缓存剩余过期时间:-2=缓存已过期/不存在;-1=永不过期;>0=剩余有效时间 long ttl = cacheBucket.remainTimeToLive(); if (ttl == -2) { // 缓存已过期,执行数据库更新 updateAccountLastAccessTime(accountId); // 重新加载最新数据到Redis并设置过期时间(示例为30分钟) refreshAccountCache(accountId, 30, TimeUnit.MINUTES); } // 缓存未过期或永不过期时,不执行任何数据库操作 }
3. 数据库日期更新操作
实现数据库层面的日期更新(以MyBatis为例):
@Autowired private AccountDao accountDao; private void updateAccountLastAccessTime(String accountId) { // 将数据库中该账户的最后访问时间更新为当前时间 accountDao.updateLastAccessDate(accountId, LocalDateTime.now()); }
4. 重新加载缓存到Redis
更新数据库后,同步最新数据到Redis:
private void refreshAccountCache(String accountId, long expireTime, TimeUnit timeUnit) { // 从数据库查询最新账户数据 Account account = accountDao.getAccountById(accountId); String cacheKey = "account:detail:" + accountId; RBucket<Object> cacheBucket = redissonClient.getBucket(cacheKey); // 将数据存入Redis并设置过期时间 cacheBucket.set(account, expireTime, timeUnit); }
注意事项
- 线程安全保障:必须使用线程安全的Map(如ConcurrentHashMap)统计访问次数,避免多线程环境下的计数错误
- 并发冲突处理:检查缓存、更新数据库、刷新缓存的流程建议加分布式锁(如Redisson的RLock),防止多个线程同时触发数据库更新
- 永不过期缓存的处理:如果业务存在永不过期的缓存(ttl=-1),需额外制定定期更新策略,避免数据库数据长期不同步
- 首次访问逻辑:首次访问(访问次数=1)时直接加载缓存/数据库数据,不触发更新,符合需求设定
内容的提问来源于stack exchange,提问作者Sai
相关产品推荐
相关产品推荐

