1. 程式人生 > 其它 >快取與資料庫雙寫不一致的問題及解決方式

快取與資料庫雙寫不一致的問題及解決方式


問題描述:當執行緒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";
    }