我试图并行执行多个读取查询。我使用ExecuterService和C3P0来实现这种情况。 现在使用executionterService的newFixedThreadPool作为1,所有查询都正常运行但是顺序运行。但是使用FixedThreadPool> 1,执行读取查询[statement.executeQuery()]时,某些线程被无限期地卡住,直到连接超时。在处理ResultSet后,resultSet,PreparredStatement和连接也被安全关闭。
我认为c3p0配置存在一些问题。这是c3p0配置 -
<bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" abstract="true">
<property name="driverClass" value="amazon.jdbc.driver.SecureDriver" />
<property name="user" ref="dbusername" />
<property name="password" ref="dbpassword" />
<property name="preferredTestQuery" value="select 1 from dual" />
<property name="testConnectionOnCheckout" value="false" />
<!-- Pool properties -->
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="40" />
<property name="maxStatements" value="50" />
<property name="idleConnectionTestPeriod" value="30" />
<property name="loginTimeout" value="300" />
<property name="checkoutTimeout" value="5000"></property>
<property name="testConnectionOnCheckin" value="true"></property>
<property name="breakAfterAcquireFailure" value="false"></property>
<property name="maxIdleTime" value="1000"></property>
<property name="maxIdleTimeExcessConnections" value="300"></property>
<property name="unreturnedConnectionTimeout" value="1000"></property>
<property name="numHelperThreads" value="7"></property>
<property name="maxConnectionAge" value="1800"></property>
<property name="connectionTesterClassName"
value="com.mchange.v2.c3p0.impl.DefaultConnectionTester"></property>
<property name="debugUnreturnedConnectionStackTraces" value="true"></property>
<property name="maxAdministrativeTaskTime" value="1500"></property>
</bean>
任何建议或帮助将不胜感激。
代码:
private static final int POOLSIZE = 5;
private ExecutorService executer = Executors
.newFixedThreadPool(POOLSIZE);
private List<String> doValidation(
final ComboPooledDataSource dataSource, final File sqlFolder) {
List<Future<String>> futureTasks = new ArrayList<>();
List<String> queryResults = new ArrayList<>();
for (final File sqlFile : sqlFolder.listFiles()) {
String sqlQuery = readSql(sqlFile);
Future<String> future = getFutureTask(sqlQuery,
dataSource);
if (future != null) {
futureTasks.add(future);
}
}
queryResults = extractValidationResponceFromFuture(
futureTasks);
return queryResults;
}
private Connection getConnection(final ComboPooledDataSource dataSource) {
try {
Connection connection = null;
connection = dataSource.getConnection();
return connection;
} catch (SQLException e) {
throw(e);
}
}
private Future<String> getFutureTask(final String sqlQuery, final ComboPooledDataSource dataSource) {
Callable<String> callable;
callable = new Callable<String>() {
@Override
public String call() throws Exception {
final String queryResult = runSql(sqlQuery, dataSource);
return queryResult;
}
};
Future<String> future = executer.submit(callable);
return future;
}
private String readSql(final File sqlFile) {
// querystring contains the query i.e content of a file
String queryString = FileUtils.readFileToString(sqlFile);
return queryString;
}
private List<String> extractValidationResponceFromFuture(
List<Future<String>> futureTasks) {
List<String> queryresponces = new ArrayList<>();
for (Future<String> futureTask : futureTasks) {
try {
S3MetaData responce = futureTask.get();
if (responce != null) {
queryresponces.add(responce);
}
} catch (InterruptedException e) {
throw new Exception(e.getMessage(),
e.getCause());
} catch (ExecutionException e) {
throw new Exception(e.getMessage(),
e.getCause());
}
}
return queryresponces;
}
private String runSql(final String query,final ComboPooledDataSource dataSource) {
PreparedStatement statement = null;
ResultSet resultSet = null;
String outputFilePath = new String();
Connection dbConnection = null;
try {
dbConnection = getConnection(dataSource);
statement = dbConnection.prepareStatement(query);
resultSet = statement.executeQuery();
String resultFileLoc = putResultInFile(resultSet);
} catch (Exception e) {
throw new SQLException(e);
} finally {
DBUtility.safeClose(resultSet, statement,
dbConnection);
}
return resultFileLoc;
}
这里是安全的连接代码,类似于结果集和预处理语句。
public static final void safeClose(final ResultSet resultSet,
final PreparedStatement statement, final Connection connection) {
safeClose(resultSet);
safeClose(statement);
safeClose(connection);
}
public static final void safeClose(final Connection connection) {
if (connection != null) {
try {
connection.close();
} catch (Exception ex) {
LOGGER.error("error while closing connection", ex);
}
}
}