@Override
public CoreDevice queryDeviceRedis(String deviceId) {
String cachDevice = stringRedisTemplate.opsForValue().get(deviceId);//查询redis里面有没有缓存
//判断缓存中数据是否存在
if (!StringUtil.isNullOrEmpty(cachDevice)) {
//缓存中存在则直接返回
try {
// 将子字符串转换为对象
CoreDevice device = objectMapper.readValue(cachDevice, CoreDevice.class);
return device;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
// 因为上面判断了cachDevice是否为空,如果进到这个方法里面则一定是空,直接过滤,不打到数据库
if (null != cachDevice) {
return null;
}
CoreDevice device = new CoreDevice();
// 缓存击穿,获取锁
String lockKey = "lock:device:" + deviceId;
try {
boolean b = tryLock(lockKey);
if (!b) {
// 获取锁失败了
Thread.sleep(50);
return queryDeviceRedis(deviceId);
}
//缓存中不存在,则从数据库里进行数据查询
device = coreDeviceMapper.selectByDeviceId(deviceId);
//数据库里不存在,返回null
if (null == device) {
// 缓存空对象
stringRedisTemplate.opsForValue().set(deviceId, "", 2, TimeUnit.MINUTES);
return null;
}
//数据库里存在,则将信息写入Redis
try {
String deviceJSon = objectMapper.writeValueAsString(device);
stringRedisTemplate.opsForValue().set(deviceId, deviceJSon, 30, TimeUnit.MINUTES);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
} catch (Exception e) {
} finally {
// 释放互斥锁
unLock(lockKey);
}
return device;
}
/**
* 尝试获取锁
*
* @param key
* @return
*/
private boolean tryLock(String key) {
Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);
return BooleanUtil.isTrue(flag);
}
/**
* 删除锁
*
* @param key
*/
private void unLock(String key) {
stringRedisTemplate.delete(key);
}