diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 256a96f3ec..7f233d6fa5 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -34,6 +34,7 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; /** @@ -55,6 +56,9 @@ public class ChartViewService { @Resource private ExtChartGroupMapper extChartGroupMapper; + //默认使用非公平 + private ReentrantLock lock = new ReentrantLock(); + public ChartViewWithBLOBs save(ChartViewWithBLOBs chartView) { checkName(chartView); long timestamp = System.currentTimeMillis(); @@ -219,8 +223,7 @@ public class ChartViewService { } else { datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList)); } - // String key = "provider_sql_"+datasourceRequest.getDatasource().getId() + "_" + datasourceRequest.getTable() + "_" +datasourceRequest.getQuery(); - // 定时抽取使用缓存 + /*// 定时抽取使用缓存 Object cache; // 仪表板有参数不实用缓存 if (CollectionUtils.isNotEmpty(requestList.getFilter())) { @@ -228,13 +231,15 @@ public class ChartViewService { } // 仪表板无参数 且 未缓存过该视图 则查询后缓存 else if ((cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, id)) == null) { + lock.lock(); data = datasourceProvider.getData(datasourceRequest); CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, id, data, null, null); } // 仪表板有缓存 使用缓存 else { data = (List) cache; - } + }*/ + data = cacheViewData(datasourceProvider, datasourceRequest, id); } if (StringUtils.containsIgnoreCase(view.getType(), "pie") && data.size() > 1000) { data = data.subList(0, 1000); @@ -301,6 +306,35 @@ public class ChartViewService { return dto; } + /** + * 避免缓存击穿 + * 虽然流量不一定能够达到击穿的水平 + * @param datasourceProvider + * @param datasourceRequest + * @param viewId + * @return + * @throws Exception + */ + public List cacheViewData(DatasourceProvider datasourceProvider, DatasourceRequest datasourceRequest, String viewId) throws Exception{ + List result ; + Object cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, viewId); + if (cache == null) { + if (lock.tryLock()) {// 获取锁成功 + result = datasourceProvider.getData(datasourceRequest); + if (result != null) { + CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, viewId, result, null, null); + } + lock.unlock(); + }else {//获取锁失败 + Thread.sleep(100);//避免CAS自旋频率过大 占用cpu资源过高 + result = cacheViewData(datasourceProvider, datasourceRequest, viewId); + } + }else { + result = (List)cache; + } + return result; + } + private void checkName(ChartViewWithBLOBs chartView) { // if (StringUtils.isEmpty(chartView.getId())) { // return;