首先考虑单删的问题
先删
先删在两个线程的并发下,就可能会出现缓存与数据库数据不一致的问题
后删
后删可以在一定程度上解决两个线程并发下的缓存与mysq不一致的问题
但是在线程数超过两个,达到三个的时候,仍有可能出现数据库数据与缓存数据不一致的问题,无法保证最终一致性,线程A修改数据,删除缓存后,线程B读取数据库数据,放入缓存前,线程C修改了数据,在线程C未删除缓存后,线程B操作缓存写入,导入数据库缓存不一致。
延时后删
采用延时后删,在并发场景下,只要延时时间合适,一定可以避免线程B将错误数据加载到缓存中的场景(缓存删除前一直读缓存数据,缓存删除后,读事务提交后的数据,出现后删中三线程并发下的缓存与mysql数据不一致场景的可能性不大),可以保证最终一致性,但是在延时删除期间,线程B会长时间读取到旧数据,这在一些场景下无法接受的。
接着考虑双删
双删
仅仅双删,在两个线程并发的场景下,就无法保证缓存与mysql的最终一致性
延时双删
伪代码
public void 延时双删{
// 减少延后删除导致的其他线程读取老数据的尝尽出现。
delCache(key);
updateMysql(data);
// 解决缓存与mysql无法保证最终一致性的问题。
sleep(time);
delCaChe(key)
}
极端场景
极端情况下,延时双删,也无法避免某个线程长时间读取老数据的问题,但是通常删除缓存与更新数据库操作的间隔比较短,所以出现这种场景的概率不是很大。
总结
采用延时双删,是为了在保证数据库与缓存数据最终一致性的情况下,尽可能的减少查询老数据场景出现的可能性。
更多推荐