在更新数据时,可能会遇到分布式事务问题,导致缓存更新成功但数据库修改失败。即使在数据库修改失败的情况下,仅删除缓存,下次查询仍会直接从数据库获取数据,不会产生脏数据。
就是在增删改某实体类的时候,要对该实体类的缓存进行清空,清空的位置在数据库操作方法的前后。
只先删
只后删
从而得出 前删和后删都有问题。所以采用延时双删的策略
依然是反证法。下图这情况是双删依然存在旧缓存的情况,延时是确保 修改数据库-》清空缓存前,其他事务的更改缓存操作已经执行完。
补充:为什么要延迟双删,来保证缓存一致性
为什么要延迟双删,来保证缓存一致性
在修改数据库数据前,需要先删除一次redis:此时是为了保证在数据库数据修改和redis数据被删除的间隔时间内,如有命中,保证此数据也不存在redis中。如果没有进行删除操作,当数据库数据已经被修改后,仍然可以从redis中读取旧数据,这将导致数据不一致。
第二次删除则是在修改数据库数据后,此时需要再次删除redis中对应数据一次,这一次是为了删除 第一次redis删除和数据库数据修改之间,如果有请求,那么旧数据又会重新缓存到redis中,然而数据在数据库中在接下来就会被修改,如果没有这一次删除,redis中则会存在数据库中旧的数据。
那么第二次为什么需要在数据库修改后延迟一定时间再删除redis呢?
为了等待之前的一次读取数据库,并等待其数据写入到缓存,最后删除这次脏数据,所以是一次数据从数据库中发到服务器+缓存写入的时间
根据综合考虑,即使先修改数据库,在删除缓存,有一定的时间会导致读取到旧数据,这通常是可以被忍受的。
只要及时将缓存删除,其他线程就可以读取到最新的值。
如果在mq中消息没有被重复消费,还会交由给其他消费者消费(将缓存删除)
以上是redis缓存延时双删指的是什么的详细内容。更多信息请关注PHP中文网其他相关文章!