快取與資料庫雙寫不一致的問題及解決方式
阿新 • • 發佈:2022-05-10
問題描述:當執行緒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"; }