c3p0线程卡住了,同时执行读取查询

时间:2015-02-10 10:20:02

标签: java multithreading oracle10g future c3p0

我试图并行执行多个读取查询。我使用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);
        }
    }
}

0 个答案:

没有答案
相关问题