This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 2d549acce13 Optimize ShardingSpherePreparedStatement for multi
executionContext (#28802)
2d549acce13 is described below
commit 2d549acce13d4148d69e3782f61f8a7eb7b4dfb1
Author: Chuxin Chen <[email protected]>
AuthorDate: Thu Oct 19 17:37:42 2023 +0800
Optimize ShardingSpherePreparedStatement for multi executionContext (#28802)
* Optimize ShardingSpherePreparedStatement for multi executionContext
* Refactor ShardingSpherePreparedStatement for support multi
executionContext.
---
.../statement/ShardingSpherePreparedStatement.java | 124 +++++++++++++--------
.../core/statement/ShardingSphereStatement.java | 18 ++-
.../proxy/backend/connector/DatabaseConnector.java | 6 +-
3 files changed, 86 insertions(+), 62 deletions(-)
diff --git
a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
index 228e07a9bce..1fefc7e0380 100644
---
a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
+++
b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.driver.jdbc.core.statement;
+import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.AccessLevel;
import lombok.Getter;
@@ -150,7 +151,7 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
@Getter
private final boolean selectContainsEnhancedTable;
- private ExecutionContext executionContext;
+ private Collection<ExecutionContext> executionContexts;
private Map<String, Integer> columnLabelAndIndexMap;
@@ -244,14 +245,8 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
if (useFederation) {
return executeFederationQuery(queryContext);
}
- executionContext = createExecutionContext(queryContext);
- List<QueryResult> queryResults = executeQuery0();
- MergedResult mergedResult = mergeQuery(queryResults);
- List<ResultSet> resultSets = getResultSets();
- if (null == columnLabelAndIndexMap) {
- columnLabelAndIndexMap =
ShardingSphereResultSetUtils.createColumnLabelAndIndexMap(sqlStatementContext,
selectContainsEnhancedTable, resultSets.get(0).getMetaData());
- }
- result = new ShardingSphereResultSet(resultSets, mergedResult,
this, selectContainsEnhancedTable, executionContext, columnLabelAndIndexMap);
+ executionContexts = createExecutionContext(queryContext);
+ result = doExecuteQuery(executionContexts);
// CHECKSTYLE:OFF
} catch (final RuntimeException ex) {
// CHECKSTYLE:ON
@@ -264,6 +259,21 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
return result;
}
+ private ShardingSphereResultSet doExecuteQuery(final
Collection<ExecutionContext> executionContexts) throws SQLException {
+ ShardingSphereResultSet result = null;
+ // TODO support multi execution context, currently
executionContexts.size() always equals 1
+ for (ExecutionContext each : executionContexts) {
+ List<QueryResult> queryResults = executeQuery0(each);
+ MergedResult mergedResult = mergeQuery(queryResults,
each.getSqlStatementContext());
+ List<ResultSet> resultSets = getResultSets();
+ if (null == columnLabelAndIndexMap) {
+ columnLabelAndIndexMap =
ShardingSphereResultSetUtils.createColumnLabelAndIndexMap(sqlStatementContext,
selectContainsEnhancedTable, resultSets.get(0).getMetaData());
+ }
+ result = new ShardingSphereResultSet(resultSets, mergedResult,
this, selectContainsEnhancedTable, each, columnLabelAndIndexMap);
+ }
+ return result;
+ }
+
private boolean decide(final QueryContext queryContext, final
ShardingSphereDatabase database, final RuleMetaData globalRuleMetaData) {
return
executor.getSqlFederationEngine().decide(queryContext.getSqlStatementContext(),
queryContext.getParameters(), database, globalRuleMetaData);
}
@@ -309,12 +319,12 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
replaySetParameter();
}
- private List<QueryResult> executeQuery0() throws SQLException {
+ private List<QueryResult> executeQuery0(final ExecutionContext
executionContext) throws SQLException {
if (hasRawExecutionRule()) {
- return
executor.getRawExecutor().execute(createRawExecutionGroupContext(),
+ return
executor.getRawExecutor().execute(createRawExecutionGroupContext(executionContext),
executionContext.getQueryContext(), new
RawSQLExecutorCallback()).stream().map(QueryResult.class::cast).collect(Collectors.toList());
}
- ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext =
createExecutionGroupContext();
+ ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext =
createExecutionGroupContext(executionContext);
cacheStatements(executionGroupContext.getInputGroups());
return
executor.getRegularExecutor().executeQuery(executionGroupContext,
executionContext.getQueryContext(),
new
PreparedStatementExecuteQueryCallback(metaDataContexts.getMetaData().getDatabase(databaseName).getProtocolType(),
@@ -351,12 +361,15 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
JDBCExecutionUnit executionUnit =
createTrafficExecutionUnit(trafficInstanceId, queryContext);
return executor.getTrafficExecutor().execute(executionUnit,
(statement, sql) -> ((PreparedStatement) statement).executeUpdate());
}
- executionContext = createExecutionContext(queryContext);
+ executionContexts = createExecutionContext(queryContext);
if (hasRawExecutionRule()) {
- Collection<ExecuteResult> executeResults =
executor.getRawExecutor().execute(createRawExecutionGroupContext(),
executionContext.getQueryContext(), new RawSQLExecutorCallback());
- return accumulate(executeResults);
+ Collection<ExecuteResult> results = new LinkedList<>();
+ for (ExecutionContext each : executionContexts) {
+
results.addAll(executor.getRawExecutor().execute(createRawExecutionGroupContext(each),
each.getQueryContext(), new RawSQLExecutorCallback()));
+ }
+ return accumulate(results);
}
- return isNeedImplicitCommitTransaction(connection,
Collections.singleton(executionContext)) ?
executeUpdateWithImplicitCommitTransaction() : useDriverToExecuteUpdate();
+ return isNeedImplicitCommitTransaction(connection,
executionContexts) ? executeUpdateWithImplicitCommitTransaction() :
useDriverToExecuteUpdate();
// CHECKSTYLE:OFF
} catch (final RuntimeException ex) {
// CHECKSTYLE:ON
@@ -368,10 +381,16 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
}
private int useDriverToExecuteUpdate() throws SQLException {
- ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext =
createExecutionGroupContext();
- cacheStatements(executionGroupContext.getInputGroups());
- return
executor.getRegularExecutor().executeUpdate(executionGroupContext,
- executionContext.getQueryContext(),
executionContext.getRouteContext().getRouteUnits(),
createExecuteUpdateCallback());
+ Integer result = null;
+ Preconditions.checkArgument(!executionContexts.isEmpty());
+ // TODO support multi execution context, currently
executionContexts.size() always equals 1
+ for (ExecutionContext each : executionContexts) {
+ ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext =
createExecutionGroupContext(each);
+ cacheStatements(executionGroupContext.getInputGroups());
+ result =
executor.getRegularExecutor().executeUpdate(executionGroupContext,
+ each.getQueryContext(),
each.getRouteContext().getRouteUnits(), createExecuteUpdateCallback());
+ }
+ return result;
}
private int accumulate(final Collection<ExecuteResult> results) {
@@ -420,13 +439,16 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
ResultSet resultSet = executeFederationQuery(queryContext);
return null != resultSet;
}
- executionContext = createExecutionContext(queryContext);
+ executionContexts = createExecutionContext(queryContext);
if (hasRawExecutionRule()) {
- // TODO process getStatement
- Collection<ExecuteResult> executeResults =
executor.getRawExecutor().execute(createRawExecutionGroupContext(),
executionContext.getQueryContext(), new RawSQLExecutorCallback());
- return executeResults.iterator().next() instanceof QueryResult;
+ Collection<ExecuteResult> results = new LinkedList<>();
+ for (ExecutionContext each : executionContexts) {
+ // TODO process getStatement
+
results.addAll(executor.getRawExecutor().execute(createRawExecutionGroupContext(each),
each.getQueryContext(), new RawSQLExecutorCallback()));
+ }
+ return results.iterator().next() instanceof QueryResult;
}
- return isNeedImplicitCommitTransaction(connection,
Collections.singleton(executionContext)) ?
executeWithImplicitCommitTransaction() : useDriverToExecute();
+ return isNeedImplicitCommitTransaction(connection,
executionContexts) ? executeWithImplicitCommitTransaction() :
useDriverToExecute();
// CHECKSTYLE:OFF
} catch (final RuntimeException ex) {
// CHECKSTYLE:ON
@@ -446,7 +468,7 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
return false;
}
- private ExecutionGroupContext<RawSQLExecutionUnit>
createRawExecutionGroupContext() throws SQLException {
+ private ExecutionGroupContext<RawSQLExecutionUnit>
createRawExecutionGroupContext(final ExecutionContext executionContext) throws
SQLException {
int maxConnectionsSizePerQuery =
metaDataContexts.getMetaData().getProps().<Integer>getValue(ConfigurationPropertyKey.MAX_CONNECTIONS_SIZE_PER_QUERY);
return new RawExecutionPrepareEngine(maxConnectionsSizePerQuery,
metaDataContexts.getMetaData().getDatabase(databaseName).getRuleMetaData().getRules())
.prepare(executionContext.getRouteContext(),
executionContext.getExecutionUnits(), new
ExecutionGroupReportContext(databaseName));
@@ -487,10 +509,16 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
}
private boolean useDriverToExecute() throws SQLException {
- ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext =
createExecutionGroupContext();
- cacheStatements(executionGroupContext.getInputGroups());
- return executor.getRegularExecutor().execute(executionGroupContext,
- executionContext.getQueryContext(),
executionContext.getRouteContext().getRouteUnits(), createExecuteCallback());
+ Boolean result = null;
+ Preconditions.checkArgument(!executionContexts.isEmpty());
+ // TODO support multi execution context, currently
executionContexts.size() always equals 1
+ for (ExecutionContext each : executionContexts) {
+ ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext =
createExecutionGroupContext(each);
+ cacheStatements(executionGroupContext.getInputGroups());
+ result =
executor.getRegularExecutor().execute(executionGroupContext,
+ each.getQueryContext(),
each.getRouteContext().getRouteUnits(), createExecuteCallback());
+ }
+ return result;
}
private JDBCExecutorCallback<Boolean> createExecuteCallback() {
@@ -510,7 +538,7 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
};
}
- private ExecutionGroupContext<JDBCExecutionUnit>
createExecutionGroupContext() throws SQLException {
+ private ExecutionGroupContext<JDBCExecutionUnit>
createExecutionGroupContext(final ExecutionContext executionContext) throws
SQLException {
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection>
prepareEngine = createDriverExecutionPrepareEngine();
return prepareEngine.prepare(executionContext.getRouteContext(),
executionContext.getExecutionUnits(), new
ExecutionGroupReportContext(databaseName));
}
@@ -526,16 +554,18 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
if (useFederation) {
return executor.getSqlFederationEngine().getResultSet();
}
- if (executionContext.getSqlStatementContext() instanceof
SelectStatementContext ||
executionContext.getSqlStatementContext().getSqlStatement() instanceof
DALStatement) {
+ if (executionContexts.iterator().next().getSqlStatementContext()
instanceof SelectStatementContext
+ ||
executionContexts.iterator().next().getSqlStatementContext().getSqlStatement()
instanceof DALStatement) {
List<ResultSet> resultSets = getResultSets();
if (resultSets.isEmpty()) {
return currentResultSet;
}
- MergedResult mergedResult =
mergeQuery(getQueryResults(resultSets));
+ SQLStatementContext sqlStatementContext =
executionContexts.iterator().next().getSqlStatementContext();
+ MergedResult mergedResult =
mergeQuery(getQueryResults(resultSets), sqlStatementContext);
if (null == columnLabelAndIndexMap) {
columnLabelAndIndexMap =
ShardingSphereResultSetUtils.createColumnLabelAndIndexMap(sqlStatementContext,
selectContainsEnhancedTable, resultSets.get(0).getMetaData());
}
- currentResultSet = new ShardingSphereResultSet(resultSets,
mergedResult, this, selectContainsEnhancedTable, executionContext,
columnLabelAndIndexMap);
+ currentResultSet = new ShardingSphereResultSet(resultSets,
mergedResult, this, selectContainsEnhancedTable,
executionContexts.iterator().next(), columnLabelAndIndexMap);
}
return currentResultSet;
}
@@ -560,19 +590,19 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
return result;
}
- private ExecutionContext createExecutionContext(final QueryContext
queryContext) {
+ private Collection<ExecutionContext> createExecutionContext(final
QueryContext queryContext) {
RuleMetaData globalRuleMetaData =
metaDataContexts.getMetaData().getGlobalRuleMetaData();
ShardingSphereDatabase currentDatabase =
metaDataContexts.getMetaData().getDatabase(databaseName);
SQLAuditEngine.audit(queryContext.getSqlStatementContext(),
queryContext.getParameters(), globalRuleMetaData, currentDatabase, null,
queryContext.getHintValueContext());
ExecutionContext result = kernelProcessor.generateExecutionContext(
queryContext, currentDatabase, globalRuleMetaData,
metaDataContexts.getMetaData().getProps(),
connection.getDatabaseConnectionManager().getConnectionContext());
findGeneratedKey(result).ifPresent(optional ->
generatedValues.addAll(optional.getGeneratedValues()));
- return result;
+ return Collections.singleton(result);
}
- private ExecutionContext createExecutionContext(final QueryContext
queryContext, final String trafficInstanceId) {
+ private Collection<ExecutionContext> createExecutionContext(final
QueryContext queryContext, final String trafficInstanceId) {
ExecutionUnit executionUnit = new ExecutionUnit(trafficInstanceId, new
SQLUnit(queryContext.getSql(), queryContext.getParameters()));
- return new ExecutionContext(queryContext,
Collections.singletonList(executionUnit), new RouteContext());
+ return Collections.singleton(new ExecutionContext(queryContext,
Collections.singletonList(executionUnit), new RouteContext()));
}
private QueryContext createQueryContext() {
@@ -583,10 +613,10 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
return new QueryContext(sqlStatementContext, sql, params,
hintValueContext, true);
}
- private MergedResult mergeQuery(final List<QueryResult> queryResults)
throws SQLException {
+ private MergedResult mergeQuery(final List<QueryResult> queryResults,
final SQLStatementContext sqlStatementContext) throws SQLException {
MergeEngine mergeEngine = new
MergeEngine(metaDataContexts.getMetaData().getDatabase(databaseName),
metaDataContexts.getMetaData().getProps(),
connection.getDatabaseConnectionManager().getConnectionContext());
- return mergeEngine.merge(queryResults,
executionContext.getSqlStatementContext());
+ return mergeEngine.merge(queryResults, sqlStatementContext);
}
private void cacheStatements(final
Collection<ExecutionGroup<JDBCExecutionUnit>> executionGroups) throws
SQLException {
@@ -629,7 +659,7 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
if (null != currentBatchGeneratedKeysResultSet) {
return currentBatchGeneratedKeysResultSet;
}
- Optional<GeneratedKeyContext> generatedKey =
findGeneratedKey(executionContext);
+ Optional<GeneratedKeyContext> generatedKey =
findGeneratedKey(executionContexts.iterator().next());
if (generatedKey.isPresent() &&
statementOption.isReturnGeneratedKeys() && !generatedValues.isEmpty()) {
return new
GeneratedKeysResultSet(getGeneratedKeysColumnName(generatedKey.get().getColumnName()),
generatedValues.iterator(), this);
}
@@ -652,8 +682,8 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
try {
QueryContext queryContext = createQueryContext();
trafficInstanceId = getInstanceIdAndSet(queryContext).orElse(null);
- executionContext = null == trafficInstanceId ?
createExecutionContext(queryContext) : createExecutionContext(queryContext,
trafficInstanceId);
-
batchPreparedStatementExecutor.addBatchForExecutionUnits(executionContext.getExecutionUnits());
+ executionContexts = null == trafficInstanceId ?
createExecutionContext(queryContext) : createExecutionContext(queryContext,
trafficInstanceId);
+
batchPreparedStatementExecutor.addBatchForExecutionUnits(executionContexts.iterator().next().getExecutionUnits());
} finally {
currentResultSet = null;
clearParameters();
@@ -662,13 +692,13 @@ public final class ShardingSpherePreparedStatement
extends AbstractPreparedState
@Override
public int[] executeBatch() throws SQLException {
- if (null == executionContext) {
+ if (null == executionContexts || executionContexts.isEmpty()) {
return new int[0];
}
try {
// TODO add raw SQL executor
initBatchPreparedStatementExecutor();
- int[] results =
batchPreparedStatementExecutor.executeBatch(executionContext.getSqlStatementContext());
+ int[] results =
batchPreparedStatementExecutor.executeBatch(executionContexts.iterator().next().getSqlStatementContext());
if (statementOption.isReturnGeneratedKeys() &&
generatedValues.isEmpty()) {
List<Statement> batchPreparedStatementExecutorStatements =
batchPreparedStatementExecutor.getStatements();
for (Statement statement :
batchPreparedStatementExecutorStatements) {
@@ -698,7 +728,7 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
ExecutionUnit executionUnit = each.getExecutionUnit();
executionUnits.add(executionUnit);
}
-
batchPreparedStatementExecutor.init(prepareEngine.prepare(executionContext.getRouteContext(),
executionUnits, new ExecutionGroupReportContext(databaseName)));
+
batchPreparedStatementExecutor.init(prepareEngine.prepare(executionContexts.iterator().next().getRouteContext(),
executionUnits, new ExecutionGroupReportContext(databaseName)));
setBatchParametersForStatements();
}
@@ -739,7 +769,7 @@ public final class ShardingSpherePreparedStatement extends
AbstractPreparedState
@Override
public boolean isAccumulate() {
return
metaDataContexts.getMetaData().getDatabase(databaseName).getRuleMetaData().findRules(DataNodeContainedRule.class).stream()
- .anyMatch(each ->
each.isNeedAccumulate(executionContext.getSqlStatementContext().getTablesContext().getTableNames()));
+ .anyMatch(each ->
each.isNeedAccumulate(executionContexts.iterator().next().getSqlStatementContext().getTablesContext().getTableNames()));
}
@Override
diff --git
a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
index d787b19f559..d675040734b 100644
---
a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
+++
b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
@@ -191,14 +191,14 @@ public final class ShardingSphereStatement extends
AbstractStatementAdapter {
private ShardingSphereResultSet doExecuteQuery(final
Collection<ExecutionContext> executionContexts) throws SQLException {
ShardingSphereResultSet result = null;
+ // TODO support multi execution context, currently
executionContexts.size() always equals 1
for (ExecutionContext each : executionContexts) {
List<QueryResult> queryResults = executeQuery0(each);
MergedResult mergedResult = mergeQuery(queryResults,
each.getSqlStatementContext());
boolean selectContainsEnhancedTable =
each.getSqlStatementContext() instanceof
SelectStatementContext && ((SelectStatementContext)
each.getSqlStatementContext()).isContainsEnhancedTable();
- if (null == result) {
- result = new ShardingSphereResultSet(getResultSets(),
mergedResult, this, selectContainsEnhancedTable, each);
- }
+ result = new ShardingSphereResultSet(getResultSets(),
mergedResult, this, selectContainsEnhancedTable, each);
+
}
return result;
}
@@ -363,15 +363,13 @@ public final class ShardingSphereStatement extends
AbstractStatementAdapter {
final Collection<ExecutionContext>
executionContexts) throws SQLException {
Integer result = null;
Preconditions.checkArgument(!executionContexts.isEmpty());
+ // TODO support multi execution context, currently
executionContexts.size() always equals 1
for (ExecutionContext each : executionContexts) {
ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext =
createExecutionGroupContext(each);
cacheStatements(executionGroupContext.getInputGroups());
JDBCExecutorCallback<Integer> callback =
createExecuteUpdateCallback(updateCallback, sqlStatementContext);
- int effectedCount =
executor.getRegularExecutor().executeUpdate(executionGroupContext,
+ result =
executor.getRegularExecutor().executeUpdate(executionGroupContext,
each.getQueryContext(),
each.getRouteContext().getRouteUnits(), callback);
- if (null == result) {
- result = effectedCount;
- }
}
return result;
}
@@ -576,15 +574,13 @@ public final class ShardingSphereStatement extends
AbstractStatementAdapter {
private boolean useDriverToExecute(final ExecuteCallback callback, final
Collection<ExecutionContext> executionContexts) throws SQLException {
Boolean result = null;
Preconditions.checkArgument(!executionContexts.isEmpty());
+ // TODO support multi execution context, currently
executionContexts.size() always equals 1
for (ExecutionContext each : executionContexts) {
ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext =
createExecutionGroupContext(each);
cacheStatements(executionGroupContext.getInputGroups());
JDBCExecutorCallback<Boolean> jdbcExecutorCallback =
createExecuteCallback(callback,
each.getSqlStatementContext().getSqlStatement());
- boolean isWrite =
executor.getRegularExecutor().execute(executionGroupContext,
+ result =
executor.getRegularExecutor().execute(executionGroupContext,
each.getQueryContext(),
each.getRouteContext().getRouteUnits(), jdbcExecutorCallback);
- if (null == result) {
- result = isWrite;
- }
}
return result;
}
diff --git
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
index 871853cec25..ee51ee8e6dc 100644
---
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
+++
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
@@ -222,11 +222,9 @@ public final class DatabaseConnector implements
DatabaseBackendHandler {
private ResponseHeader doExecute(final Collection<ExecutionContext>
executionContexts) throws SQLException {
ResponseHeader result = null;
+ // TODO support multi execution context, currently
executionContexts.size() always equals 1
for (ExecutionContext each : executionContexts) {
- ResponseHeader responseHeader = doExecute(each);
- if (null == result) {
- result = responseHeader;
- }
+ result = doExecute(each);
}
return result;
}