延时双删的代码:
public void write(String key,Object data){
redisUtils.del(key);
db.update(data);
Thread.Sleep(100);
redisUtils.del(key);
}
上面的代码确实存在一个问题,尤其是在 高并发 的情况下。问题在于,当多个请求同时到来时,缓存失效 的情况可能导致多个请求同时从数据库读取数据,然后重新写入缓存,从而导致缓存不一致的情况。对于 write
方法的改进,已经使用了延时双删策略,确保缓存被删除并更新,但在高并发环境下依然有改进空间。
问题解析:
-
高并发问题:多个请求(请求A、请求B等)同时访问相同的缓存,并且缓存未命中时,都会去访问数据库并更新缓存。假如缓存被删除后,在并发的情况下,多个请求会同时进行数据库查询,造成重复查询数据库和重复写入缓存的情况。
-
Thread.sleep(100)
:这段代码的延时仅仅是为了给主从同步提供时间,但在高并发的环境下,延时的时间并不一定能保证所有请求都能顺利地从数据库获取正确的数据并更新缓存。
优化方案:
1. 加锁机制:
使用分布式锁来确保在缓存失效时,只有一个请求能访问数据库并更新缓存,其他请求将等待锁释放后,从缓存中读取数据。这样避免了高并发情况下多个请求同时查询数据库的问题。
示例代码: