我使用tomcat-connection-pool运行带有gradle的Spring-Boot。所有标准的弹簧启动工具。我在该网络服务器上运行了几个soap-webservices。在测试服务器的负载时,一切正常。但是在7.5小时内无所事事之后会发生这种异常。当然它是timeout
,但我尝试使用以下内容来阻止它:
spring.datasource.url=jdbc:postgresql://mydb?autoReconnect=true
@transactional
。但一般来说,我只使用spring-boot中的JPA-Repository
。我的数据库服务器运行PostgreSQL 9.4.1 on x86_64-unknown-linux-gnu
,数据库和应用服务器之间没有防火墙。
我需要tcp_keep alives吗?
为什么我的连接会在一段时间后中断并且不再可恢复?
我的应用程序属性:
#
# [ Database Configuration Section ]
#
spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=false
hibernate.format_sql=true
hibernate.hbm2ddl.auto=validate
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
spring.datasource.platform=postgres
spring.database.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://*****:5434/******
spring.datasource.username=*****
spring.datasource.password=*****
logging.file=*******.log
logging.level.=WARNING
2015-09-29 11:58:50.598 INFO 10498 --- [nio-9092-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2015-09-29 11:58:50.598 INFO 10498 --- [nio-9092-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2015-09-29 11:58:50.674 INFO 10498 --- [nio-9092-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 76 ms
2015-09-29 19:23:03.777 WARN 10498 --- [ool-3-thread-16] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 08006
2015-09-29 19:23:03.779 ERROR 10498 --- [ool-3-thread-16] o.h.engine.jdbc.spi.SqlExceptionHelper : An I/O error occurred while sending to the backend.
2015-09-29 19:23:03.785 INFO 10498 --- [ool-3-thread-16] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2015-09-29 19:23:03.836 ERROR 10498 --- [ool-3-thread-16] o.s.orm.jpa.JpaTransactionManager : Commit exception overridden by rollback exception
java.net.SocketException: Connection timed out
at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.8.0_25]
at java.net.SocketInputStream.read(SocketInputStream.java:150) ~[na:1.8.0_25]
at java.net.SocketInputStream.read(SocketInputStream.java:121) ~[na:1.8.0_25]
at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:143) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:112) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:71) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:282) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1718) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
... 61 common frames omitted
Wrapped by: org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:201) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:615) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:465) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:411) ~[postgresql-9.4-1202-jdbc41.jar!/:9.4]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
... 57 common frames omitted
Wrapped by: org.hibernate.exception.JDBCConnectionException: could not execute statement
编辑:
我已经添加了这个并正在测试它:
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
已移除autoReconnect
。
答案 0 :(得分:4)
正如@Yuki Yoshida所说,答案很简单。
我补充说
spring.datasource.validation-query= select 1
spring.datasource.test-on-borrow=true
我的配置,它的工作原理。
试验上借:
testOnBorrow:默认值:true
是否验证对象的指示 在从游泳池借来之前。如果对象无法验证, 它将从池中丢弃,我们将尝试借用 另一个。
和
validationQuery:默认值:对于大多数数据库语言select 1
,请参阅here
validationQuery
将用于验证的SQL查询 在将它们返回给调用者之前来自此池的连接。如果 指定,此查询必须是返回at的SQL SELECT语句 至少一排。如果未指定,则连接将通过验证 调用isValid()方法。
我实际上已经尝试了这个,但由于默认情况,我没有明确将test-on-borrow设置为true。看起来你必须明确地设置它。