BaseController 缓存调整

v1.4.1
Parker 4 years ago
parent 32ddade22f
commit 6485197c1c

@ -45,11 +45,10 @@ import org.opsli.core.cache.local.CacheUtil;
import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.CoreMsg;
import org.opsli.core.msg.TokenMsg; import org.opsli.core.msg.TokenMsg;
import org.opsli.core.security.shiro.realm.JwtRealm; import org.opsli.core.security.shiro.realm.JwtRealm;
import org.opsli.core.utils.DistributedLockUtil;
import org.opsli.core.utils.ExcelUtil; import org.opsli.core.utils.ExcelUtil;
import org.opsli.core.utils.UserUtil; import org.opsli.core.utils.UserUtil;
import org.opsli.plugins.excel.exception.ExcelPluginException; import org.opsli.plugins.excel.exception.ExcelPluginException;
import org.opsli.plugins.redis.RedisLockPlugins;
import org.opsli.plugins.redis.lock.RedisLock;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -98,10 +97,6 @@ public abstract class BaseRestController <T extends BaseEntity, E extends ApiWra
@Autowired(required = false) @Autowired(required = false)
protected S IService; protected S IService;
/** Redis分布式锁 */
@Autowired
private RedisLockPlugins redisLockPlugins;
/** Excel工具类 */ /** Excel工具类 */
@Autowired @Autowired
private ExcelUtil excelUtil; private ExcelUtil excelUtil;
@ -115,81 +110,81 @@ public abstract class BaseRestController <T extends BaseEntity, E extends ApiWra
*/ */
@ModelAttribute @ModelAttribute
public E get(@RequestParam(required=false) String id) { public E get(@RequestParam(required=false) String id) {
E model = null; E model;
if (StringUtils.isNotBlank(id)){ if (StringUtils.isNotBlank(id)){
// 如果开启缓存 先从缓存读 // 如果开启缓存 先从缓存读
if(hotDataFlag){ if(hotDataFlag){
// 缓存Key
String cacheKey = CacheConstants.HOT_DATA_PREFIX +"::"+ id;
model = WrapperUtil.transformInstance( model = WrapperUtil.transformInstance(
CacheUtil.getTimed(entityClazz, CacheConstants.HOT_DATA_PREFIX +"::"+ id) CacheUtil.getTimed(entityClazz, cacheKey)
, modelClazz); , modelClazz);
if(model != null){ if(model != null){
return model; return model;
} }
}
// 防止缓存穿透判断 // 防止缓存穿透判断
boolean hasNilFlag = false; boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
// 如果开启缓存 防止缓存穿透判断 if(hasNilFlag){
if(hotDataFlag){ return null;
hasNilFlag = CacheUtil.hasNilFlag("get::" + id); }
}
if(!hasNilFlag){ try {
// 锁凭证 redisLock 贯穿全程 // 分布式加锁
RedisLock redisLock = new RedisLock(); if(!DistributedLockUtil.lock(cacheKey)){
redisLock.setLockName("getLock::"+id) // 无法申领分布式锁
.setAcquireTimeOut(3000L) log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
.setLockTimeOut(10000L); throw new ServiceException(CoreMsg.CACHE_PUNCTURE_EXCEPTION);
// 这里增加分布式锁 防止缓存击穿 }
if(hotDataFlag){
try { // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
// 加锁 model = WrapperUtil.transformInstance(
redisLock = redisLockPlugins.tryLock(redisLock); CacheUtil.getTimed(entityClazz, cacheKey)
if(redisLock == null){ , modelClazz);
throw new ServiceException(CoreMsg.CACHE_PUNCTURE_EXCEPTION); if(model != null){
} return model;
// 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
model = WrapperUtil.transformInstance(
CacheUtil.getTimed(entityClazz, CacheConstants.HOT_DATA_PREFIX +"::"+ id)
, modelClazz);
if(model != null){
return model;
}
// 如果缓存没读到 则去数据库读
model = WrapperUtil.transformInstance(IService.get(id), modelClazz);
}catch (Exception e){
log.error(e.getMessage(), e);
}finally {
// 释放锁
redisLockPlugins.unLock(redisLock);
} }
}else{
// 如果缓存没读到 则去数据库读 // 如果缓存没读到 则去数据库读
model = WrapperUtil.transformInstance(IService.get(id),modelClazz); model = WrapperUtil.transformInstance(IService.get(id), modelClazz);
}
// 获得数据后处理 // 获得数据后处理
if(model != null){ if(model != null){
// 如果开启缓存 将数据库查询对象 存如缓存
if(hotDataFlag){
// 这里会 同步更新到本地Ehcache 和 Redis缓存 // 这里会 同步更新到本地Ehcache 和 Redis缓存
// 如果其他服务器缓存也丢失了 则 回去Redis拉取 // 如果其他服务器缓存也丢失了 则 回去Redis拉取
CacheUtil.put(id, model); CacheUtil.put(cacheKey, model);
} }
}else { }catch (Exception e){
log.error(e.getMessage(), e);
}finally {
// 释放锁
DistributedLockUtil.unlock(cacheKey);
}
if(model == null){
// 设置空变量 用于防止穿透判断 // 设置空变量 用于防止穿透判断
CacheUtil.putNilFlag("get::" + id); CacheUtil.putNilFlag(cacheKey);
return null;
}
return model;
}else {
// 如果没开启缓存 则直接查询数据库
model = WrapperUtil.transformInstance(IService.get(id), modelClazz);
if(model != null){
return model;
} }
} }
} }
if (model == null){
try { // 如果参数没传入ID 则创建一个空的对象
// 创建泛型对象 try {
model = this.createModel(); // 创建泛型对象
}catch (Exception e){ model = this.createModel();
log.error(CommonMsg.EXCEPTION_CONTROLLER_MODEL.toString()+" : {}",e.getMessage()); }catch (Exception e){
throw new ServiceException(CommonMsg.EXCEPTION_CONTROLLER_MODEL); log.error(CommonMsg.EXCEPTION_CONTROLLER_MODEL.toString()+" : {}",e.getMessage());
} throw new ServiceException(CommonMsg.EXCEPTION_CONTROLLER_MODEL);
} }
return model; return model;
} }

Loading…
Cancel
Save