day102-Cache-Cache Usage-Locking to solve the problem of cache breakdown and the importance of locking position

1. lock

    @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;
    }

pressure test

why? I will say later

2. Improved locking logic

Under the improvement, the data obtained from the cache is also added to the lock logic

    @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;
    }

The pressure test was performed again, and the result was normal, and the database was queried only once

Therefore, when locking, it is very important to think about the logic of the lock code block. The above is because when the lock is waiting, because the locking place is wrong, the first few threads will be in a stage where the query data in the cache is empty, and then the first thread Save data after execution

After the cache, the thread coming in will get the data from the cache. This is the reason why there are multiple queries from the database.

Guess you like

Origin blog.csdn.net/JavaCoder_juejue/article/details/113706591