H2中如何防止validationQueryTimeout影响其他SQL语句

我正在使用由 H2 1.4.199 数据库支持的 Dropwizard 1.3.12。在我的数据库配置中


database:

  ...

  validationQuery: "/* MyService Health Check */ SELECT 1"

  validationQueryTimeout: 3s

  ...

我遇到的问题是 3 秒的超时也会传播到 Dropwizard 应用程序中完成的真实数据库查询。某些数据库查询被此超时中断。我宁愿让他们多等一会儿。


从我的理解validationQueryTimeout应该只控制超时validationQuery。在应用程序内部完成的真实数据库请求不应受此影响。我试过删除validationQueryTimeout,这似乎可以解决问题并删除查询超时。这样做我认为是最后的解决方法,因为我认为在从连接池获取连接时验证连接已启动并正在运行的查询超时是有意义的。


我尝试使用 Postgresql,但似乎validationQueryTimeout不会影响其他数据库查询。


我已经进行了一些调试,并认为我找到了原因,但我缺乏一个好的解决方法。


在执行验证时,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

     */


有什么我可以做的吗?或者 h2 或 tomcat-jdbc 是否需要修复?我能想到的是在为验证查询设置当前查询超时值之前获取 tomcat-jdbc 中的当前查询超时值,然后在运行验证查询后将其设置回该值。


青春有我
浏览 179回答 1
1回答

拉丁的传说

没错,这是 H2 的一个已知限制(请参阅此处和此处)我想您可以将超时设置为 0 以避免 H2 的错误行为。然后实现一个JdbcInterceptor语句执行后检查超时的方法。但是,当它违反超时时它不会中止语句只会在之后报告异常:-(
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java