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

Mar*_*ace 5 java postgresql spring jdbc spring-jdbc

当我PSQLException: This connection has been closed尝试访问 AWS RDS 中的 Postgres 数据库时,出现以下错误消息:异常是随机发生的(并非每次运行代码时都会发生),如果执行到以下代码之前需要一段时间,则更有可能发生:

@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();
                }
            });
Run Code Online (Sandbox Code Playgroud)

连接东西:

spring.datasource.url=jdbc:postgresql://my-url:port/dbName?tcpKeepAlive=true&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>
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

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(本机方法)
    在 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.ReflectiveMethodInspiration.invokeJoinpoint(ReflectiveMethodInspiration.java:190)
    在 org.springframework.aop.framework.ReflectiveMethodInitation.proceed(ReflectiveMethodInitation.java:157)
    在 org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInitation(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.ReflectiveMethodInitation.proceed(ReflectiveMethodInitation.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(本机方法)
    在 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(本机方法)
    在 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个常用帧

小智 4

看起来数据库和池之间的连接丢失了。尝试设置removeAbandoned和removeAbandonedTimeout选项。有关这些选项的更多信息,请阅读JDBC 连接池文档