day102-キャッシュ-キャッシュ使用量-キャッシュの故障の問題とロック位置の重要性を解決するためのロック

1.ロック

    @Override
    public Map<String, List<Catelog2Vo>> getCatalogJson() {
        //先从缓存中尝试获取,若为空则从数据库中获取然后放入缓存
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        String catalogJson = opsForValue.get("catalogJson");
        System.out.println("从缓存内查询...");
        synchronized (this) {
            if (StringUtils.isEmpty(catalogJson)) {
                Map<String, List<Catelog2Vo>> catalogJsonFromDb = getCatalogJsonFromDb();
                System.out.println("从数据库内查询...");
                String str = JSON.toJSONString(catalogJsonFromDb);
                opsForValue.set("catalogJson", str, 1, TimeUnit.DAYS);
                return catalogJsonFromDb;
            }
        }

        Map<String, List<Catelog2Vo>> catalogJsonFromCache = JSON.parseObject(catalogJson, new TypeReference<Map<String, List<Catelog2Vo>>>() {
        });
        return catalogJsonFromCache;
    }

圧力試験

どうして?後で言います

2.改善されたロックロジック

改善により、キャッシュから取得したデータもロックロジックに追加されます

    @Override
    public Map<String, List<Catelog2Vo>> getCatalogJson() {
        //先从缓存中尝试获取,若为空则从数据库中获取然后放入缓存
        String catalogJson;
        synchronized (this) {
            ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
            catalogJson = opsForValue.get("catalogJson");
            System.out.println("从缓存内查询...");
            if (StringUtils.isEmpty(catalogJson)) {
                Map<String, List<Catelog2Vo>> catalogJsonFromDb = getCatalogJsonFromDb();
                System.out.println("从数据库内查询...");
                String str = JSON.toJSONString(catalogJsonFromDb);
                opsForValue.set("catalogJson", str, 1, TimeUnit.DAYS);
                return catalogJsonFromDb;
            }
        }

        Map<String, List<Catelog2Vo>> catalogJsonFromCache = JSON.parseObject(catalogJson, new TypeReference<Map<String, List<Catelog2Vo>>>() {
        });
        return catalogJsonFromCache;
    }

圧力テストが再度実行され、結果は正常であり、データベースは1回だけ照会されました。

したがって、ロックするときは、ロックコードブロックのロジックを考慮することが非常に重要です。上記は、ロックが間違っているためにロックが待機しているため、最初の数スレッドはキャッシュ内のクエリデータの段階になります。空の場合、最初のスレッドは実行後にデータを保存します

キャッシュの後、入ってくるスレッドはキャッシュからデータを取得します。これが、データベースから複数のクエリがある理由です。

おすすめ

転載: blog.csdn.net/JavaCoder_juejue/article/details/113706591