gpt4 book ai didi

spring - 使用 tomcat 池和 Spring 在 postgres 中自动重新连接

转载 作者:行者123 更新时间:2023-11-29 11:30:06 25 4
gpt4 key购买 nike

据我所知,“testOnBorrow”和“validationQuery”参数正合我意,但它们似乎没有按预期工作。

我启动应用程序,运行一些查询,一切正常。然后我重新启动 postgres 服务器 - 不重新启动 tomcat - 以测试数据源可以处理重新连接,我得到的是:

    This connection has been closed.; nested exception is org.postgresql.util.PSQLException: This connection has been closed.
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:104)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:666)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:674)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:729)

...

Caused by: org.postgresql.util.PSQLException: This connection has been closed.
at org.postgresql.jdbc2.AbstractJdbc2Connection.checkClosed(AbstractJdbc2Connection.java:822)
at org.postgresql.jdbc3.AbstractJdbc3Connection.prepareStatement(AbstractJdbc3Connection.java:273)
at org.postgresql.jdbc2.AbstractJdbc2Connection.prepareStatement(AbstractJdbc2Connection.java:301)
at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:67)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
at org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:153)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
at org.apache.tomcat.jdbc.pool.TrapException.invoke(TrapException.java:41)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:63)
at $Proxy35.prepareStatement(Unknown Source)
at org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1436)

我正在使用:

  • Spring 3.1
  • PostgreSQL 9.2.1
  • 连接池:org.apache.tomcat.jdbc.pool 7.0.25

我的Spring bean配置如下:

public DataSource dataSource() {
org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
// from properties file
dataSource.setDriverClassName(environment
.getProperty("datasource.driver"));
dataSource.setUrl(environment.getProperty("datasource.url"));
dataSource.setUsername(environment.getProperty("datasource.username"));
dataSource.setPassword(environment.getProperty("datasource.password"));
// other configurations
dataSource.setInitialSize(10);
dataSource.setMinIdle(10);
dataSource.setMaxIdle(100);
dataSource.setMaxActive(100);
dataSource.setDefaultAutoCommit(true);
dataSource.setMaxWait(6000);
dataSource.setJmxEnabled(true);
dataSource
.setJdbcInterceptors("....ConnectionState;.....StatementFinalizer");
dataSource.setRemoveAbandoned(true);
dataSource.setRemoveAbandonedTimeout(10);
dataSource.setLogAbandoned(true);
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(false);
dataSource.setTestWhileIdle(false);
dataSource.setUseEquals(false);
dataSource.setFairQueue(false);
dataSource.setTimeBetweenEvictionRunsMillis(30000);
dataSource.setMinEvictableIdleTimeMillis(30000);
dataSource.setValidationInterval(1800000);
dataSource.setValidationQuery("SELECT 1");

return dataSource;
}

有什么想法吗?

谢谢

最佳答案

连接的验证仅在最初从池中借用时进行。即使在每次查询之前都进行了检查,在检查和查询之间仍然有一段时间可能会丢失连接。所有查询都应该有某种形式的异常处理来处理查询失败——一般来说,处理错误的连接句柄,获取新的连接句柄,然后重试查询(如果可能)。

在 JDBC 标准中有一个“connectionErrorOccurred”的回调方法,只要发生这种情况就应该调用它,但我对 JDBC 和 Java 的工作原理还不够熟悉,不知道如何使用它(或者即使它涵盖了这种情况)。

在任何情况下,您唯一能知道连接是好是坏的时间是在您尝试使用它的时候,没有连接池可以自动克服这个问题而不使用自定义调用来执行和重试查询,这会打破 JDBC 与标准接口(interface)的“契约”。

关于spring - 使用 tomcat 池和 Spring 在 postgres 中自动重新连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13688730/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com