Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgres连接已关闭在Spring引导中出错_Spring_Postgresql_Spring Boot - Fatal编程技术网

Postgres连接已关闭在Spring引导中出错

Postgres连接已关闭在Spring引导中出错,spring,postgresql,spring-boot,Spring,Postgresql,Spring Boot,我正在运行一个springboot应用程序来创建restapi。我经常会收到一个错误,说数据库连接已关闭,然后我就无法对应用程序进行任何调用。我用的是Postgres数据库。这是完整的堆栈跟踪: org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistenc

我正在运行一个springboot应用程序来创建restapi。我经常会收到一个错误,说数据库连接已关闭,然后我就无法对应用程序进行任何调用。我用的是Postgres数据库。这是完整的堆栈跟踪:

org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed: 
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:457)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy91.findByUriMoniker(Unknown Source)
    at com.mypkg.businessobjects.OrderInfoBO.getOrderInfo(OrderInfoBO.java:76)
    at com.mypkg.controller.OrderInfoController.getOrderInfo(OrderInfoController.java:78)
    at sun.reflect.GeneratedMethodAccessor104.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130)
    at com.mypkg.config.CORSFilter.doFilter(CORSFilter.java:39)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)
    at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:247)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:76)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:166)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:759)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed: 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1771)
    at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:64)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:159)
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380)
    ... 56 more
Caused by: org.hibernate.TransactionException: JDBC begin transaction failed: 
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:76)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162)
    at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1435)
    at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61)
    ... 58 more
Caused by: org.postgresql.util.PSQLException: This connection has been closed.
    at org.postgresql.jdbc2.AbstractJdbc2Connection.checkClosed(AbstractJdbc2Connection.java:833)
    at org.postgresql.jdbc2.AbstractJdbc2Connection.getAutoCommit(AbstractJdbc2Connection.java:794)
    at sun.reflect.GeneratedMethodAccessor35.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108)
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81)
    at com.sun.proxy.$Proxy56.getAutoCommit(Unknown Source)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:68)
    ... 61 more

当我重新启动应用程序时,它就会消失。我想这个问题发生在我重新启动postgres DB时。为什么会发生这种情况?

这是一个非常有效的问题,许多人通常都会面临这个问题。当池和数据库之间的网络连接丢失时(大部分时间是由于重新启动),通常会发生异常。查看您指定的堆栈跟踪,很明显您正在使用
jdbc池
来获取连接
JDBC池
提供了微调各种连接池设置的选项,并记录池内发生的事情的详细信息

您可以参考以指定放弃超时

检查RemoveBandOned、RemoveBandOnedTimeout和LogUndered参数

此外,还可以使用其他属性进一步加强验证

使用testXXX和validationQuery检查连接有效性


我遇到了完全相同的问题,也使用(
org.apache.tomcat.jdbc.pool
)连接到Heroku Postgres:

org.springframework.transaction.CannotCreateTransactionException: 
    Could not open JPA EntityManager for transaction
org.hibernate.TransactionException: JDBC begin transaction failed: ] 
    with root cause
org.postgresql.util.PSQLException: This connection has been closed.
解决这个问题的方法是将其添加到DataSource init代码中(借用):

我不确定这三项是否都是获得稳定连接所必需的,也许不是,但启用这三项功能可能不会造成太大伤害


JavaDocs澄清了正在发生的事情:参见示例。也许有点奇怪,默认情况下没有进行这样的测试

这是其他帖子回答的一半,我想说得非常清楚。我还想更像春天的靴子。如有必要,请随时更改时间间隔

选项1:从池中抛出断开的连接。

使用以下属性:

spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1;
spring.datasource.validation-interval=30000
spring.datasource.test-while-idle=true
spring.datasource.validation-query=SELECT 1;
spring.datasource.time-between-eviction-runs-millis=60000
选项2:保持池中的连接处于活动状态。

使用以下属性:

spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1;
spring.datasource.validation-interval=30000
spring.datasource.test-while-idle=true
spring.datasource.validation-query=SELECT 1;
spring.datasource.time-between-eviction-runs-millis=60000
选项3:主动丢弃空闲连接。

使用这些属性(注意:我找不到有关Spring Boot的可靠文档。超时时间以秒为单位,而不是以毫秒为单位):


开机快乐

我也有同样的问题,但在我的情况下,上述答案没有帮助。我发现,当执行长查询时,会出现相同的错误。在我的例子中,我调用了findAll(Iterable id),并传递了一个超过10万个id的庞大列表。对列表进行分区(例如,使用Apache Commons或Google Guava中的ListUtils)并使用较少的ID调用findAll(),这样做了。

此异常基本上表示JDBC连接已关闭,但这并不意味着 数据库服务器未运行(还有另一个例外)。当数据库服务器重新启动时,可能会发生这种情况 或者在DB服务器断开连接后(例如,由于超时)。 因此,这里的问题是为什么应用程序不在新的HTTP请求上重新连接到服务器

通常,这是连接池的错误配置,每次应用程序启动时都应该验证连接 “借”一个。解决此问题所需的全部内容如下:

spring.datasource.validation-query=SELECT 1;
spring.datasource.test-on-borrow=true
其他配置参数(来自其他答案)是此异常不严格要求的优化

但有时,即使正确配置了JDBC池,也可能存在应用程序持有DB连接的特定应用程序错误 在HTTP请求结束后,不将其返回到JDBC池。 因此JDBC池甚至不可能验证DB连接(它只知道DB连接是“已分配的”)。 这里的一般解决方案是确保应用程序返回连接,并在每个HTTP请求上“借用”一个新连接

此类错误的一个示例:

@Component
public MyService {
    @Resource
    private EntityManagerFactory emf;
    
    private EntityManager em;
    
    public MyService() {
         em = emf.createEntityManager();//em never return back its JDBC connection to the pool (using em.close())
    }
}
上述错误的解决方案是使用注入/管理的EntityManager(首选)

或者,如果您确实需要自己管理它,请为每个HTTP请求创建一个EntityManager,如果确实需要,请在try finally块中关闭它

@Component
public MyService {
    @Resource
    private EntityManagerFactory emf;
    
    private EntityManager em;
    
    public void myMethod() {
         EntityManager em = emf.createEntityManager();
         try {
         
         } finaly {
            em.close();//do not forget other cleanup operations like rolling back the transaction
         }
    }
}

当您在存储库中编写查询时,请尝试将@Component annotation保留在存储库中

此解决方案对您有帮助吗?我有一个类似的问题,但这对我没有帮助。@Mark.ewd:如果仍然相关,您可以在Spring Boot中尝试,如果您自动配置数据源,如果使用了正确的驱动程序类(例如org.postgresql.Driver),池也会自动配置。您可以通过在application.properties中提供以下属性来调整池:spring.datasource.teston-borrow=true,spring.datasource.remove-audded=true,spring.datasource.validation-query=SELECT 1;我看到一个与此相关的问题——“不能在事务中间更改事务隔离级别”。我删除了上面评论中提到的这些设置,它开始正常工作。知道为什么吗?@Tisha,我没有建议更改隔离级别设置。请检查数据库驱动程序手册,并检查是否需要配置任何其他设置以启用放弃连接。Spring Boot 1.4更明确地指出,这些设置特定于池实现,因为它们需要正确地加前缀(例如
spring.datasource.tomcat
spring.datasource.dbcp
spring.datasource.dbcp2
,或
spring.datasource.hikari
)而不仅仅是
spring.datasource
。spring的松散绑定将只将它们传递给底层连接池实现。检查文档中您正在使用的特定池的正确配置参数是什么……上面的内容对于tomcat和dbcp来说看起来不错,但hikari有点不同。
@Component
public MyService {
    @Resource
    private EntityManagerFactory emf;
    
    private EntityManager em;
    
    public void myMethod() {
         EntityManager em = emf.createEntityManager();
         try {
         
         } finaly {
            em.close();//do not forget other cleanup operations like rolling back the transaction
         }
    }
}