缓存与数据库双写不一致的问题及解决方式
问题描述:当线程1正常更新数据库并删除redis的数据 ,在线程2第一次查询时,线程3更新数据并删除redis的数据,这时线程2才执行到更新redis,就会出现数据库与缓存双写不一致的问题。
一般而言,我们在更新数据库时会把redis的值删除掉,然后第一次查询时从数据库查询并且更新到redis中。但从数据库查询然后更新到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"; }