Я использую Dropwizard 1.3.12 с базой данных H2 1.4.199.В конфигурации базы данных у меня есть
database:
...
validationQuery: "/* MyService Health Check */ SELECT 1"
validationQueryTimeout: 3s
...
Проблема, с которой я сталкиваюсь, состоит в том, что тайм-аут 3 с также распространяется на реальные запросы к БД, выполненные в приложении Dropwizard.Некоторые запросы к БД прерываются этим тайм-аутом.Я бы предпочел, чтобы они подождали немного дольше.
Насколько я понимаю, validationQueryTimeout
должен контролировать только время ожидания validationQuery
.Это не должно влиять на реальные запросы к БД, выполняемые внутри приложения.Я попытался удалить validationQueryTimeout
, и это, кажется, делает трюк и удаляет таймаут запроса.Делая это, я рассматриваю это как крайнее решение, поскольку думаю, что имеет смысл установить таймаут для запроса, который проверяет, что соединение установлено и работает при извлечении соединения из пула соединений.
Я пытался использовать Postgresqlи validationQueryTimeout
, похоже, не влияет на другие запросы к БД.
Я провел некоторую отладку и думаю, что нашел причину, но мне не хватает хорошего обходного пути.
При выполненииvalidation tomcat-jdbc устанавливает время ожидания запроса в операторе проверки.https://github.com/apache/tomcat/blob/9.0.16/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java#L536-L544
stmt = connection.createStatement();
int validationQueryTimeout = poolProperties.getValidationQueryTimeout();
if (validationQueryTimeout > 0) {
stmt.setQueryTimeout(validationQueryTimeout);
}
stmt.execute(query);
stmt.close();
Большая проблема заключается в том, что H2 сохраняет время ожидания на уровне соединения, а не на уровне операторов.https://github.com/h2database/h2database/blob/version-1.4.199/h2/src/main/org/h2/jdbc/JdbcStatement.java#L695-L717
/**
* Sets the current query timeout in seconds.
* Changing the value will affect all statements of this connection.
* This method does not commit a transaction,
* and rolling back a transaction does not affect this setting.
*
* @param seconds the timeout in seconds - 0 means no timeout, values
* smaller 0 will throw an exception
* @throws SQLException if this object is closed
*/
@Override
public void setQueryTimeout(int seconds) throws SQLException {
try {
debugCodeCall("setQueryTimeout", seconds);
checkClosed();
if (seconds < 0) {
throw DbException.getInvalidValueException("seconds", seconds);
}
conn.setQueryTimeout(seconds);
} catch (Exception e) {
throw logAndConvert(e);
}
}
Могу ли я что-нибудь сделать?Или требуется исправление в h2 или tomcat-jdbc?Я могу подумать о том, чтобы получить текущее значение тайм-аута запроса в tomcat-jdbc, прежде чем устанавливать его для запроса проверки, а затем вернуть его к этому значению после выполнения запроса проверки.