복붙노트

[SPRING] 스프링 부트에서 Postgres 연결이 닫혔다.

SPRING

스프링 부트에서 Postgres 연결이 닫혔다.

나는 REST API를 생성하기 위해 Spring Boot 애플리케이션을 실행 중이다. 종종 데이터베이스 연결이 닫혔다는 오류가 발생하고 그 이후에는 응용 프로그램에 대한 호출을 할 수 없습니다. Postgres DB를 사용하고 있습니다. 다음은 완전한 스택 추적입니다.

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

응용 프로그램을 다시 시작하면 사라집니다. 내 포스트그레스 DB를 다시 시작할 때이 문제가 발생한다고 생각합니다. 왜 이런 일이 일어나는 걸까요?

해결법

  1. ==============================

    1.매우 유효한 질문이며이 문제는 일반적으로 많은 사람들이 직면합니다. 예외는 일반적으로 풀과 데이터베이스간에 네트워크 연결이 끊어지면 발생합니다 (대부분 재시작으로 인해 발생합니다). 지정한 스택 추적을 보면 jdbc 풀을 사용하여 연결을 확보하고 있다는 것이 확실합니다. JDBC 풀은 다양한 커넥션 풀 설정을 세부적으로 조정하고 풀 내부에서 수행되는 작업에 대한 세부 정보를 기록하는 옵션을 제공합니다.

    매우 유효한 질문이며이 문제는 일반적으로 많은 사람들이 직면합니다. 예외는 일반적으로 풀과 데이터베이스간에 네트워크 연결이 끊어지면 발생합니다 (대부분 재시작으로 인해 발생합니다). 지정한 스택 추적을 보면 jdbc 풀을 사용하여 연결을 확보하고 있다는 것이 확실합니다. JDBC 풀은 다양한 커넥션 풀 설정을 세부적으로 조정하고 풀 내부에서 수행되는 작업에 대한 세부 정보를 기록하는 옵션을 제공합니다.

    풀 구성에 대한 자세한 아파치 문서를 참조하여 포기할 시간 초과를 지정할 수 있습니다

    또한 추가 속성을 사용하여 유효성을 더욱 강화할 수 있습니다.

  2. ==============================

    2.이것은 다른 게시물들에 의해 절반의 답변을 얻었으며 나는 아주 명백하게 말하고 싶었습니다. 또한 저는 더 많은 Spring-Boot-esque가되고 싶었습니다. 필요에 따라 시간 간격을 자유롭게 변경하십시오.

    이것은 다른 게시물들에 의해 절반의 답변을 얻었으며 나는 아주 명백하게 말하고 싶었습니다. 또한 저는 더 많은 Spring-Boot-esque가되고 싶었습니다. 필요에 따라 시간 간격을 자유롭게 변경하십시오.

    옵션 1 : 풀에서 깨진 연결을 제거합니다.

    다음 속성을 사용하십시오.

    spring.datasource.test-on-borrow=true
    spring.datasource.validation-query=SELECT 1;
    spring.datasource.validation-interval=30000
    

    옵션 2 : 풀에 연결을 유지하십시오.

    다음 속성을 사용하십시오.

    spring.datasource.test-while-idle=true
    spring.datasource.validation-query=SELECT 1;
    spring.datasource.time-between-eviction-runs-millis=60000
    

    옵션 3 : 유휴 연결을 사전에 던지십시오.

    이 속성을 사용하십시오 (참고 : Spring Boot 용으로 신뢰할 수있는 문서를 찾을 수 없었습니다. 또한 제한 시간은 밀리 초가 아닌 초입니다).

    spring.datasource.remove-abandoned=true
    spring.datasource.remove-abandoned-timeout=60
    

    해피 부팅!

  3. ==============================

    3.이 설치로 Tomcat (org.apache.tomcat.jdbc.pool)의 DataSource를 사용하여 Heroku Postgres에 연결하는 것과 똑같은 문제가 발생했습니다.

    이 설치로 Tomcat (org.apache.tomcat.jdbc.pool)의 DataSource를 사용하여 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 초기화 코드 (Grails 질문에서 빌려)이 추가 :

    dataSource.setTestOnBorrow(true);
    dataSource.setTestWhileIdle(true);
    dataSource.setTestOnReturn(true);
    dataSource.setValidationQuery("SELECT 1");
    

    이 세 가지가 모두 안정적인 연결을 필요로하는지 확신 할 수는 없습니다.하지만 아마도 사용하지 않는 것이 아마도별로 다치게하지는 못할 것입니다.

    JavaDocs에서는 진행 상황을 분명히합니다. setTestOnBorrow (). 조금 놀랍기는하지만, 기본적으로 그러한 테스트는 수행되지 않습니다.

  4. ==============================

    4.나는 정확히 같은 문제가 있었지만 나의 경우에는 앞에서 언급 한 답변이 도움이되지 못했다. 긴 쿼리를 수행 할 때 같은 오류가 나타납니다. 필자의 경우 findAll (Iterable ids)을 호출하고 100,000 개가 넘는 엄청난 목록을 통과시켰다. 목록을 분할 (예 : Apache Commons 또는 Google 구아바의 ListUtils 사용)하고 적은 수의 findAll ()을 호출하면 트릭을 수행합니다.

    나는 정확히 같은 문제가 있었지만 나의 경우에는 앞에서 언급 한 답변이 도움이되지 못했다. 긴 쿼리를 수행 할 때 같은 오류가 나타납니다. 필자의 경우 findAll (Iterable ids)을 호출하고 100,000 개가 넘는 엄청난 목록을 통과시켰다. 목록을 분할 (예 : Apache Commons 또는 Google 구아바의 ListUtils 사용)하고 적은 수의 findAll ()을 호출하면 트릭을 수행합니다.

  5. from https://stackoverflow.com/questions/29620265/postgres-connection-has-been-closed-error-in-spring-boot by cc-by-sa and MIT license