一般而言,我们在更新数据库时会把redis的值删除掉,然后第一次查询时从数据库查询并且更新到redis中。但从数据库查询然后更新到redis中这并不是原子操作,可能出现并发问题。
问题描述:当线程1正常更新数据库并删除redis的数据 ,在线程2第一次查询时,线程3更新数据并删除redis的数据,这时线程2才执行到更新redis,就会出现数据库与缓存双写不一致的问题。
使用redisson读写锁来解决
@RequestMapping("/getStock")
public String getStock(){
String lockKey = "product_01001";
//获取一个读锁
RReadWriteLock readWriteLock = redisson.getReadWriteLock(lockKey);
RLock rLock = readWriteLock.readLock();
//加锁
rLock.lock();
String stock = stringRedisTemplate.opsForValue().get("stock");
if (StringUtils.isEmpty(stock)){
System.out.println("查询对应商品的id的库存");
stringRedisTemplate.opsForValue().set("stock","数据库查询出来的值");
}else{
return "stock";
}
//解锁
rLock.unlock();
return "stock";
}
@RequestMapping("/updateStock")
public String updateStock(){
String lockKey = "product_01001";
//获取一个写锁
RReadWriteLock readWriteLock = redisson.getReadWriteLock(lockKey);
RLock rLock = readWriteLock.writeLock();
//加锁
rLock.lock();
System.out.println("更新数据库对应商品的id的库存");
stringRedisTemplate.delete("stock");
//解锁
rLock.unlock();
return "end";
}