protected List<Object> executeInConcurrency( SqlSessionCallback action, SortedMap<String, DataSource> dsMap) { List<ConcurrentShardRequest> requests = Lists.newArrayList(); for (Map.Entry<String, DataSource> entry : dsMap.entrySet()) { ConcurrentShardRequest request = new ConcurrentShardRequest(); request.setAction(action); request.setDataSource(entry.getValue()); request.setExecutor(dataSourceSpecificExecutors.get(entry.getKey())); requests.add(request); } return getConcurrentShardRequestProcessor().process(requests); }
private ExecutorService createExecutorForSpecificDataSource(ShardDataSourceSpec dataSourceSpec) { final String identity = dataSourceSpec.getIdentity(); final ExecutorService executor = createCustomExecutorService( dataSourceSpec.getPoolSize(), "createExecutorForSpecificDataSource-" + identity + " data source"); // 1. register executor for disposing explicitly internalExecutorServiceRegistry.add(executor); // 2. dispose executor implicitly Runtime.getRuntime() .addShutdownHook( new Thread() { @Override public void run() { if (executor == null) { return; } try { executor.shutdown(); executor.awaitTermination(5, TimeUnit.MINUTES); } catch (InterruptedException e) { logger.warn("interrupted when shuting down the query executor:\n{}", e); } } }); return executor; }
@Override public Map<?, ?> selectMap( final String statementName, final Object parameterObject, final String mapKey, final RowBounds rowBounds) { if (isSqlAuditorBehaviorEnabled()) { getSqlAuditor() .audit( statementName, getSqlByStatementName(statementName, parameterObject), parameterObject); } if (isPartitioningBehaviorEnabled()) { SortedMap<String, DataSource> dsMap = lookupDataSourcesByRouter(statementName, parameterObject); if (dsMap != null && !dsMap.isEmpty()) { SqlSessionCallback action = new SqlSessionCallback<Map<?, ?>>() { @Override public Map<?, ?> doInSession(SqlSession sqlSession) { return sqlSession.selectMap(statementName, parameterObject, mapKey, rowBounds); } }; if (dsMap.size() == 1) { return (Map<?, ?>) executeWith(dsMap.get(dsMap.firstKey()), action); } else { List<Object> results = executeInConcurrency(action, dsMap); Map<?, ?> retVal = Maps.newHashMap(); if (results != null && !results.isEmpty()) { for (int i = 0; i < results.size(); i++) { retVal.putAll((Map) results.get(i)); } } return retVal; } } } return super.selectMap(statementName, parameterObject, mapKey, rowBounds); }
/** * 更新记录 * * @param statementName * @param parameterObject * @return */ @Override public int update(final String statementName, final Object parameterObject) { if (isSqlAuditorBehaviorEnabled()) { getSqlAuditor() .audit( statementName, getSqlByStatementName(statementName, parameterObject), parameterObject); } if (isPartitioningBehaviorEnabled()) { SortedMap<String, DataSource> dsMap = lookupDataSourcesByRouter(statementName, parameterObject); if (dsMap != null && !dsMap.isEmpty()) { SqlSessionCallback action = new SqlSessionCallback() { @Override public Object doInSession(SqlSession sqlSession) { return sqlSession.update(statementName, parameterObject); } }; if (dsMap.size() == 1) { return (Integer) executeWith(dsMap.get(dsMap.firstKey()), action); } else { List<Object> results = executeInConcurrency(action, dsMap); Integer rowAffected = 0; if (results != null && !results.isEmpty()) { for (Object item : results) { rowAffected += (Integer) item; } } return rowAffected; } } } return super.update(statementName, parameterObject); }
@Override public void destroy() throws Exception { if (internalExecutorServiceRegistry.isEmpty()) { logger.info("开始释放相关资源"); for (ExecutorService executor : internalExecutorServiceRegistry) { if (executor != null) { try { executor.shutdown(); executor.awaitTermination(5, TimeUnit.MINUTES); executor = null; } catch (InterruptedException e) { logger.warn("interrupted when shuting down the query executor:\n{}", e); } } } getDataSourceSpecificExecutors().clear(); logger.info("所有相关资源释放完闭"); } }