use of org.sagacity.sqltoy.config.model.SqlExecuteTrace in project sagacity-sqltoy by chenrenfei.
the class DialectFactory method parallelPage.
/**
* @update data:2021-01-25 分页支持并行查询
* @TODO 并行分页查询,同时执行count和rows记录查询
* @param sqlToyContext
* @param queryExecutor
* @param sqlToyConfig
* @param extend
* @param pageNo
* @param pageSize
* @param pageOptimize
* @param conn
* @param dbType
* @param dialect
* @return
* @throws Exception
*/
private QueryResult parallelPage(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final SqlToyConfig sqlToyConfig, final QueryExecutorExtend extend, final long pageNo, final Integer pageSize, PageOptimize pageOptimize, Connection conn, Integer dbType, String dialect) throws Exception {
final QueryResult queryResult = new QueryResult();
queryResult.setPageNo(pageNo);
queryResult.setPageSize(pageSize);
ExecutorService pool = null;
try {
SqlExecuteStat.debug("过程提示", "分页查询开始并行查询count总记录数和单页记录数据!");
final SqlExecuteTrace sqlTrace = SqlExecuteStat.get();
pool = Executors.newFixedThreadPool(2);
// 查询总记录数量
pool.submit(new Runnable() {
@Override
public void run() {
try {
// 规避新的线程日志无法采集
SqlExecuteStat.mergeTrace(sqlTrace);
Long startTime = System.currentTimeMillis();
queryResult.setRecordCount(getCountBySql(sqlToyContext, sqlToyConfig, queryExecutor, conn, dbType, dialect));
SqlExecuteStat.debug("查询count执行耗时", (System.currentTimeMillis() - startTime) + "毫秒!");
if (sqlTrace != null && SqlExecuteStat.get() != null) {
sqlTrace.addLogs(SqlExecuteStat.get().getExecuteLogs());
}
} catch (Exception e) {
e.printStackTrace();
queryResult.setSuccess(false);
queryResult.setMessage("查询总记录数异常:" + e.getMessage());
} finally {
SqlExecuteStat.destroyNotLog();
}
}
});
// 获取记录
pool.submit(new Runnable() {
@Override
public void run() {
try {
SqlExecuteStat.mergeTrace(sqlTrace);
Long startTime = System.currentTimeMillis();
QueryResult result = getDialectSqlWrapper(dbType).findPageBySql(sqlToyContext, sqlToyConfig, queryExecutor, wrapDecryptHandler(sqlToyContext, extend.resultType), pageNo, pageSize, conn, dbType, dialect, getFetchSize(extend.fetchSize), extend.maxRows);
queryResult.setRows(result.getRows());
queryResult.setLabelNames(result.getLabelNames());
queryResult.setLabelTypes(result.getLabelTypes());
SqlExecuteStat.debug("查询分页记录耗时", (System.currentTimeMillis() - startTime) + "毫秒!");
if (sqlTrace != null && SqlExecuteStat.get() != null) {
sqlTrace.addLogs(SqlExecuteStat.get().getExecuteLogs());
}
} catch (Exception e) {
e.printStackTrace();
queryResult.setSuccess(false);
queryResult.setMessage("查询单页记录数据异常:" + e.getMessage());
} finally {
SqlExecuteStat.destroyNotLog();
}
}
});
pool.shutdown();
// 设置最大等待时长(秒)
if (pageOptimize.getParallelMaxWaitSeconds() > 0) {
pool.awaitTermination(pageOptimize.getParallelMaxWaitSeconds(), TimeUnit.SECONDS);
} else {
pool.awaitTermination(SqlToyConstants.PARALLEL_MAXWAIT_SECONDS, TimeUnit.SECONDS);
}
// 发生异常
if (!queryResult.isSuccess()) {
throw new DataAccessException("并行查询执行错误:" + queryResult.getMessage());
}
int rowSize = (queryResult.getRows() == null) ? 0 : queryResult.getRows().size();
// 修正实际结果跟count的差异,比如:pageNo=3,rows=9,count=27,则需要将count调整为29
long minCount = (queryResult.getPageNo() - 1) * queryResult.getPageSize() + rowSize;
// 总记录数小于实际查询记录数量(rowSize <= queryResult.getPageSize() 防止单页数据关联扩大了记录量的场景)
if (queryResult.getRecordCount() < minCount && minCount >= 0 && rowSize <= queryResult.getPageSize()) {
queryResult.setRecordCount(minCount);
}
// 总记录数量大于实际记录数量
if (rowSize < queryResult.getPageSize() && (queryResult.getRecordCount() > minCount) && minCount >= 0) {
queryResult.setRecordCount(minCount);
}
if (queryResult.getRecordCount() == 0 && sqlToyContext.isPageOverToFirst()) {
queryResult.setPageNo(1L);
}
} catch (Exception e) {
e.printStackTrace();
throw new DataAccessException("并行查询执行错误:" + e.getMessage(), e);
} finally {
if (pool != null) {
pool.shutdownNow();
}
}
return queryResult;
}
use of org.sagacity.sqltoy.config.model.SqlExecuteTrace in project sagacity-sqltoy by chenrenfei.
the class SqlExecuteStat method destroyLog.
/**
* 在执行结尾时记录日志
*/
private static void destroyLog() {
try {
SqlExecuteTrace sqlTrace = threadLocal.get();
if (sqlTrace == null) {
return;
}
long runTime = sqlTrace.getExecuteTime();
long overTime = runTime - printSqlTimeoutMillis;
// sql执行超过阀值记录日志为软件优化提供依据
if (overTime >= 0) {
sqlTrace.setOverTime(true);
sqlTrace.addLog("slowSql执行超时", "耗时(毫秒):{} >={} (阀值)!", runTime, printSqlTimeoutMillis);
} else {
sqlTrace.addLog("执行时长", "耗时:{} 毫秒 !", runTime);
}
// 日志输出
printLogs(sqlTrace);
} catch (Exception e) {
}
}
use of org.sagacity.sqltoy.config.model.SqlExecuteTrace in project sagacity-sqltoy by chenrenfei.
the class TranslateManager method getCacheData.
/**
* @todo 提供对外的访问(如要做增量更新可以对这里的数据进行修改即可达到缓存的更新作用)
* @param cacheName
* @param cacheType (一般为null,不为空时一般用于数据字典等同于dictType)
* @return
*/
public HashMap<String, Object[]> getCacheData(String cacheName, String cacheType) {
TranslateConfigModel cacheModel = translateMap.get(cacheName);
if (cacheModel == null) {
logger.error("cacheName:{} 没有配置,请检查sqltoy-translate.xml文件!", cacheName);
return null;
}
// 获得当前线程中的sql执行日志,后续缓存获取会覆盖掉日志
SqlExecuteTrace sqlTrace = SqlExecuteStat.get();
HashMap<String, Object[]> result = getCacheData(cacheModel, cacheType);
// 将调用获取缓存之前的日志放回线程中
if (sqlTrace != null) {
SqlExecuteStat.set(sqlTrace);
}
return result;
}
use of org.sagacity.sqltoy.config.model.SqlExecuteTrace in project sagacity-sqltoy by chenrenfei.
the class TranslateManager method getTranslates.
/**
* @todo 根据sqltoy sql.xml中的翻译设置获取对应的缓存(多个translate对应的多个缓存结果)
* @param translates
* @return
*/
public HashMap<String, HashMap<String, Object[]>> getTranslates(HashMap<String, Translate> translates) {
// 获得当前线程中的sql执行日志,后续缓存获取会覆盖掉日志
SqlExecuteTrace sqlTrace = SqlExecuteStat.get();
HashMap<String, HashMap<String, Object[]>> result = new HashMap<String, HashMap<String, Object[]>>();
HashMap<String, Object[]> cache;
TranslateConfigModel cacheModel;
TranslateExtend extend;
int cacheEltLength;
for (Map.Entry<String, Translate> entry : translates.entrySet()) {
extend = entry.getValue().getExtend();
if (translateMap.containsKey(extend.cache)) {
cacheModel = translateMap.get(extend.cache);
cache = getCacheData(cacheModel, extend.cacheType);
if (cache != null) {
// update 2022-1-4 增加缓存使用时cache-index 合法性校验
if (cache.size() > 0) {
cacheEltLength = cache.values().iterator().next().length;
if (extend.index >= cacheEltLength) {
throw new IllegalArgumentException("缓存取值数组越界:cacheName:" + extend.cache + ", column:" + extend.column + ",cache-indexs:(" + extend.index + ">=" + cacheEltLength + ")[缓存内容数组长度],请检查cache-indexs值确保跟缓存数据具体列保持一致!");
}
}
result.put(extend.column, cache);
} else {
result.put(extend.column, new HashMap<String, Object[]>());
if (logger.isWarnEnabled()) {
logger.warn("sqltoy translate:cacheName={},cache-type={},column={}配置不正确,未获取对应cache数据!", cacheModel.getCache(), extend.cacheType, extend.column);
} else {
System.err.println("sqltoy translate:cacheName=" + cacheModel.getCache() + ",cache-type=" + extend.cacheType + ",column=" + extend.column + " 配置不正确,未获取对应cache数据!");
}
}
} else {
logger.error("cacheName:{} 没有配置,请检查sqltoy-translate.xml文件!", extend.cache);
}
}
// 将调用获取缓存之前的日志放回线程中
if (sqlTrace != null) {
SqlExecuteStat.set(sqlTrace);
}
return result;
}
Aggregations