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.