缓存数据库双写一致性问题

先写缓存,再写数据库

先操作缓存,在写数据库成功之前,如果有读请求发生,可能导致旧数据入缓存,引发数据不一致

可以考虑用redisson的读写锁实现

先写数据库,再写缓存

会出现数据库中是新数据,缓存中是旧数据的情况,

所以我们需要保证 DB 和缓存的操作,能够在“同一个事务”中,从而实现最终一致性

  • 方式一:基于Lua脚本实现
// 把数据库原子性操作和redis原子性操作放到同一个事物中
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public void updateDBAndRedis() {

  // 1、更新DB

  // 2、Lua脚本批量原子性执行redis更新操作
}
  • 方式二:基于消息中间件实现

缓存数据库双写一致性问题_第1张图片

如果更新Redis失败,同时在将数据发到MQ之前的时间,应用重启了,这时候MQ就没有需要更新的数据,如果Redis对所有数据没有设置过期时间(一般都会设置),同时在读多写少的场景下,只能通过人工介入来更新缓存

  • 方式三:采用binlog方式解决一致性,客户端数据库与缓存解耦(而且这个方案虽然比较重,但却容易形成统一的解决方案)

缓存数据库双写一致性问题_第2张图片

 

 

你可能感兴趣的:(redis)