Как исправить ошибку "Нет доступных управляемых соединений в течение настроенного времени блокировки (60000 [мс]) "
Я развернул java
заявка на wildfly-15.0.1.FINAl
Сервер. Я использую OJDBC 12.1.0.2.0
Водитель.
<datasource jndi-name="java:/DS_APP" pool-name="APP" enabled="true" use-java-context="true">
<connection-url>jdbc:oracle:thin:@localhost:1521:MYDB</connection-url>
<driver>OracleJDBCDriver</driver>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<pool>
<min-pool-size>3</min-pool-size>
<max-pool-size>200</max-pool-size>
</pool>
<security>
<security-domain>Password4APP</security-domain>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
</validation>
<timeout>
<blocking-timeout-millis>60000</blocking-timeout-millis>
<idle-timeout-minutes>15</idle-timeout-minutes>
</timeout>
<statement>
<track-statements>true</track-statements>
<prepared-statement-cache-size>100</prepared-statement-cache-size>
</statement>
</datasource>
Был период, когда мое приложение не могло подключиться к базе данных и регистрировало такие ошибки
Caused by: java.sql.SQLException: javax.resource.ResourceException: IJ000453: Unable to get managed connection for java:/DS_APP
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:146) ~[?:?]
at org.jboss.as.connector.subsystems.datasources.WildFlyDataSource.getConnection(WildFlyDataSource.java:64) ~[?:?]
at ge.app.ws.util.DbManager.getDatabaseConnection(DbManager.java:55) ~[classes:?]
... 2 more
Caused by: javax.resource.ResourceException: IJ000453: Unable to get managed connection for java:/DS_APP
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.getManagedConnection(AbstractConnectionManager.java:690) ~[?:?]
at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.getManagedConnection(TxConnectionManagerImpl.java:440) ~[?:?]
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:789) ~[?:?]
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:138) ~[?:?]
at org.jboss.as.connector.subsystems.datasources.WildFlyDataSource.getConnection(WildFlyDataSource.java:64) ~[?:?]
at ge.app.ws.util.DbManager.getDatabaseConnection(DbManager.java:55) ~[classes:?]
... 2 more
Caused by: javax.resource.ResourceException: IJ000655: No managed connections available within configured blocking timeout (60000 [ms])
at org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool.getConnection(SemaphoreConcurrentLinkedDequeManagedConnectionPool.java:570) ~[?:?]
at org.jboss.jca.core.connectionmanager.pool.AbstractPool.getSimpleConnection(AbstractPool.java:632) ~[?:?]
at org.jboss.jca.core.connectionmanager.pool.AbstractPool.getConnection(AbstractPool.java:604) ~[?:?]
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.getManagedConnection(AbstractConnectionManager.java:624) ~[?:?]
at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.getManagedConnection(TxConnectionManagerImpl.java:440) ~[?:?]
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:789) ~[?:?]
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:138) ~[?:?]
at org.jboss.as.connector.subsystems.datasources.WildFlyDataSource.getConnection(WildFlyDataSource.java:64) ~[?:?]
at ge.app.ws.util.DbManager.getDatabaseConnection(DbManager.java:55) ~[classes:?]
... 2 more
Я читал много блогов об этой ошибке, но моя точка зрения другая. Из блогов я нашел несколько проблемных вопросов:
- Может быть, у вас есть утечка соединения. Вы не закрываете соединения
- Что я сделал: я проверил каждую строку моего кода, и я уверен, что каждый
Connection
а такжеCallableStatement
закрываются.
- Что я сделал: я проверил каждую строку моего кода, и я уверен, что каждый
- Возможно, все соединения из пула уже используются. Попробуйте увеличить размер пула соединений, который является значением по умолчанию. 20
- Что я сделал: Когда возникла эта проблема, я проверил соединения на стороне базы данных, и не было активных соединений, все соединения были неактивными, также у меня есть 200 соединений в пуле, что так много, у меня одновременно максимум 30 активных сессий и у меня есть 60 Второй раз, чтобы ждать, пока соединения из пула не будут свободны.
Когда я перезапустил свой Wildfly
На сервере проблема решена, но меня интересует, почему возникли эти ошибки, могут ли быть такие ошибки в будущем (думаю, они возникнут снова) и как их избежать?
0 ответов
Недавно я столкнулся с той же проблемой. И, как вы упомянули, возможные решения для этого исправления - это иметь дело с
- Конфигурация источника данных
- Утечки при закрытии соединений.
Я попытался изменить конфигурацию источника данных, установив максимальный размер пула на 20, как это, но я получил ту же ошибку после нажатия 21-го запроса.
Я включил статистику в конфигурации источника данных и проверил статистику пула в конфигурации jboss console->datasource и обнаружил, что соединения создаются, но не закрываются.
Вы не получите эту ошибку после перезапуска, потому что все эти соединения будут сброшены, и 20 новых соединений будут доступны для обслуживания.
Поэтому я попытался отследить утечки соединения и добавил следующие конфигурации, которые вручную закрывали соединение с источником данных и регистрировали ошибку, если есть утечка соединения. https://access.redhat.com/solutions/309913
Это решило мою проблему, но это не может быть постоянным решением, поэтому перепроверили код, чтобы увидеть, где произошла утечка соединения. Затем я изменил код, чтобы правильно закрыть источник данных.
Я думал, что это сработает, но этого не произошло (исходный код):
try {
Connection dbConnect = dataSource.getConnection();
Statement stmt = dbConnect.createStatement();
ResultSet rs = stmt.executeQuery("select s from soething");
stmt.close();
dbConnect.close();
return something;
} catch (SQLException e) {
LOGGER.log(Level.INFO, e.getMessage());
return e.getMessage();
}
Это сработает (окончательный код с аккуратно закрытыми источниками данных):
Statement stmt=null;
Connection dbConnect=null;
try {
dbConnect = dataSource.getConnection();
stmt = dbConnect.createStatement();
ResultSet rs = stmt.executeQuery("select s from soething");
return something;
} catch (SQLException e) {
LOGGER.log(Level.INFO, e.getMessage());
return e.getMessage();
}finally{
if (stmt != null) stmt.close();
if (dbConnect != null) dbConnect.close();
}