Соединение Websphere с jdbc недоступно - PullRequest
0 голосов
/ 18 марта 2019

У меня есть сервлет, который возвращает данные в формате json.Я пытаюсь выполнить несколько запросов в цикле.Если массив запросов содержит менее 5 запросов, он работает хорошо.Но если я попытаюсь выполнить 10 запросов в цикле, он сложится и вернет NullPointerExceprion.здесь мой код

private JSONArray getQueryResultJSONById(String queryId, String formName, JSONObject paramsJSON) {
String sql = getQuery(queryId, formName);
if (sql != null) {
    try {
        Connector connector = new Connector(Defaults.DS_DEFAULT);
        connector.prepareStatement(sql);
        connector.setPreparedJSONParams(paramsJSON);
        connector.executePrepared();
        JSONArray dbrs = ResultSetConverter.convertToJSON(connector.getPreparedSelect());
        connector.close();
        return dbrs;
    } catch (Exception e) {
        e.printStackTrace();
    }
}
return null;
}

Класс соединителя:

public void prepareStatement(String query) {
    try {
        this.sql = query;
        if (connection.isClosed()) {
            connection = dataSource.getConnection();
        }
        preparedStatement = connection.prepareStatement(query);
    } catch (Exception e) {
        logException(e);
    }
}
public void setPreparedJSONParams(JSONObject paramsJSON) {
    if (paramsJSON != null) {
        JSONArray array = paramsJSON.getJSONArray("params");
        for (int i = 0; i < array.length(); i++) {
            String paramValue = array.getString(i);
            if (NULL.equals(paramValue)) {
                setPreparedParam(i + 1, (String) null);
            } else {
                setPreparedParam(i + 1, array.getString(i));
            }
        }
    }
}
public boolean executePrepared() {
    try {
        preparedStatement.executeUpdate();
        return true;
    } catch (Exception e) {
        logException(e);
        return false;
    }
}
public ResultSet getPreparedSelect() {
    ResultSet resultSet = null;
    try {
        resultSet = preparedStatement.executeQuery();
    } catch (Exception e) {
        logException(e);
    }
    return resultSet;
}
public void close() {
    try {
        if (statement != null) {
            statement.close();
        }
        if (connection != null) {
            connection.close();
        }
        if (preparedStatement != null) {
            preparedStatement.close();
        }
    } catch (Exception e) {
        logException(e);
    }
}

в цикле, я пытаюсь сделать так, чтобы выполнить запросы:

queryRs = new JSONArray(uiQueryService.getQueryResultById(querys.get(i), "REPORT", params.toString()));

Я пытался отладить это месточтобы увидеть, какой запрос порождает проблему, но в отладчике каждый запрос работает хорошо и результат успешно возвращается.Я понятия не имею, как решить проблему

исключение:

J2CA0045E: Во время вызова метода createOrWaitForConnection для ресурса jdbc/Oep/NonXaDataSourceWeb соединение недоступно.
[18.03.19 13:08:33:025 MSK] 0000f40e TaskUtils$Log E org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler handleError Unexpected error occurred in scheduled task.
                                 org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException: CWTE_NORMAL_J2CA1009
                at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:243)
                at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
                at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:420)
                at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:257)
                at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
                at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
                at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
                at com.sun.proxy.$Proxy158.pollDiagnosisLock(Unknown Source)
                at sun.reflect.GeneratedMethodAccessor209.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56)
                at java.lang.reflect.Method.invoke(Method.java:620)
                at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
                at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
                at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
                at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:483)
                at java.util.concurrent.FutureTask.run(FutureTask.java:274)
                at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:190)
                at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1157)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:627)
                at java.lang.Thread.run(Thread.java:809)
Caused by: com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException: CWTE_NORMAL_J2CA1009
                at com.ibm.ws.rsadapter.AdapterUtil.toSQLException(AdapterUtil.java:1680)
                at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:661)
                at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:611)
                at sun.reflect.GeneratedMethodAccessor41.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56)
                at java.lang.reflect.Method.invoke(Method.java:620)
                at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
                at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
                at com.sun.proxy.$Proxy123.getConnection(Unknown Source)
                at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:205)
                ... 20 more
Caused by: com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException: CWTE_NORMAL_J2CA1009
                at com.ibm.ejs.j2c.FreePool.createOrWaitForConnection(FreePool.java:1783)
                at com.ibm.ejs.j2c.PoolManager.reserve(PoolManager.java:3874)
                at com.ibm.ejs.j2c.PoolManager.reserve(PoolManager.java:3094)
                at com.ibm.ejs.j2c.ConnectionManager.allocateMCWrapper(ConnectionManager.java:1548)
                at com.ibm.ejs.j2c.ConnectionManager.allocateConnection(ConnectionManager.java:1031)
                at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:644)
                ... 28 more

1 Ответ

1 голос
/ 18 марта 2019

Такое ощущение, что у вас кончились связи.

В connection.close() есть две ошибки: вам нужно закрыть подготовленный оператор, оператор и затем соединение (обратный порядок, в котором вы создали эти ресурсы).

Может быть, один из них создает исключение, и тогда соединение никогда не закрывается. Так что ищите больше ошибок в вашем журнале и используйте этот код:

if (x != null) {
    try { x.close(); } catch(Exception e) { log.warn("Failed to close X", e); }
}

т.е. обрабатывать исключение для каждого вызова close(), поэтому другие ресурсы также закрываются.

Если это не помогает, посмотрите, как используется и разработан Connector. Обычно приложение может создать только несколько (около 10) подключений к базе данных одновременно. Поэтому приложения используют пул соединений, который обрабатывает создание и закрытие соединений. Когда вы попросите новое соединение, вы получите прокси для одного в пуле. Это означает, что каждое реальное соединение JDBC используется для многих операторов SQL и запросов до его закрытия.

Таким образом, приложение не может истощить базу данных, открыв тысячи дорогих соединений, и все еще использует простой дизайн «открывать / закрывать соединения».

...