PSQLException:此连接已关闭 - Spring Boot + AWS RDS + Postgres

Posted

技术标签:

【中文标题】PSQLException:此连接已关闭 - Spring Boot + AWS RDS + Postgres【英文标题】:PSQLException: This connection has been closed - Spring Boot + AWS RDS + Postgres 【发布时间】:2015-04-25 09:13:15 【问题描述】:

我在尝试访问 AWS RDS 中的 Postgres 数据库时收到 PSQLException: This connection has been closed。异常是随机发生的(不是我每次运行代码),如果在执行到达下面的代码之前需要一段时间,则更有可能发生:

@Transactional
public void revokeChanges(ArrayList<Integer> changeIds) 
    jdbcTemplate.batchUpdate(sqlUpdate,
            new BatchPreparedStatementSetter() 
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException 
                    ps.setStuff..
                    ...
                
                @Override
                public int getBatchSize() 
                    return changeIds.size();
                
            );
    jdbcTemplate.batchUpdate(sqlInsert,
            new BatchPreparedStatementSetter() 
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException 
                    ps.setStuff...
                
                @Override
                public int getBatchSize() 
                    return changeIds.size();
                
            );

连接材料:

spring.datasource.url=jdbc:postgresql://my-url:port/dbName?tcpKeepAlive=true&amp;autoReconnect=true

spring.datasource.driver-class-name=org.postgresql.Driver

相关POM:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.1.9.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.3-1102-jdbc41</version>
    </dependency>

堆栈跟踪:

org.springframework.jdbc.support.MetaDataAccessException:提取DatabaseMetaData时出错;嵌套异常是 org.postgresql.util.PSQLException:此连接已关闭。 在 org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:296) 在 org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:320) 在 org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:214) 在 org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:134) 在 org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.(SQLErrorCodeSQLExceptionTranslator.java:97) 在 org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99) 在 org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660) 在 org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:673) 在 org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:989) 在 my.package.DataServiceJdbc.revokeChanges(DataServiceJdbc.java:71) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:483) 在 org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 在 org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 在 com.sun.proxy.$Proxy24.revokeChanges(未知来源) 在 my.package.DataExporterS3ToPostgre.exportData(DataExporterS3ToPostgre.java:59) 在 my.package.Application.main(Application.java:41) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:483) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) 引起:org.postgresql.util.PSQLException:此连接已关闭。 在 org.postgresql.jdbc2.AbstractJdbc2Connection.checkClosed(AbstractJdbc2Connection.java:843) 在 org.postgresql.jdbc4.Jdbc4Connection.getMetaData(Jdbc4Connection.java:54) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:483) 在 org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) 在 org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) 在 org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:80) 在 com.sun.proxy.$Proxy23.getMetaData(未知来源) 在 org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:285) ...省略了29个常用框架

【问题讨论】:

正如我在其他回答中提到的:I had exactly the same problem ... I figured out that when doing a long query the same error appears. In my case I called findAll(Iterable ids) and passed a huge list of more than 100'000 ids. Partitioning the list (e.g. using ListUtils from Apache Commons or Google Guava) and calling the findAll() with less ids did the trick. 【参考方案1】:

DB 和池之间的连接似乎丢失了。尝试设置 removeAbandoned 和 removeAbandonedTimeout 选项。有关这些选项的更多数据,请阅读JDBC Connection Pool docs。

【讨论】:

以上是关于PSQLException:此连接已关闭 - Spring Boot + AWS RDS + Postgres的主要内容,如果未能解决你的问题,请参考以下文章

代理 XP”组件已作为此服务器安全配置的一部分被关闭。系统管理员可以使用 sp_configure 来启用“代理 XP”。

在通过 HTTPS 连接到 SHA256 CA 安装的 Windows 2003 Server SP2 时,Android 7.0 Nougat 中出现“连接已关闭”错误

“代理XP”组件已作为此服务器安全配置的一部分被关闭的解决办法

无法验证连接(此连接已关闭。)。可能考虑使用更短的 maxLifetime 值

Flyway jdbc迁移连接问题

HikariPool-1 - 无法验证连接 org.postgresql.jdbc.PgConnection@2a84e649(此连接已关闭。)