我正在开发环境中的 Spring-Boot
项目中使用 data-envers
。
当微服务运行大约 8 小时后,与数据库的连接停止工作(仅限与 data-envers
一起使用的查询,即任何使用 JPA
的查询> 例如继续工作)。
每次我重新启动微服务 (pod) 时,与数据库的连接都会再次工作,并且使用 data-envers
进行的查询会再次工作(大约又需要 8 小时)。
我读过很多关于 SO 的文章和帖子,但它们对我不起作用。 我已将以下属性添加到我的 .yml 文件中:
testOnBorrow : true
validationQuery : SELECT 1
我还添加了
url: jdbc:mysql://localhost:3306/mydatabase?autoReconnect=true
并且无法重新连接。
我已经更新了 Hikari
的版本,因为我也读到它可能是这样,但事实并非如此。
我的 data-envers
版本是 2.7.6
有什么想法可以防止连接关闭或自动重新连接吗?
这是我的 .yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mydatabase?autoReconnect=true
username: X
password: X
testOnBorrow : true
validationQuery : SELECT 1
hikari:
connection-timeout: 20000
maximum-pool-size: 5
和堆栈跟踪:
java.sql.SQLException: Connection is closed
at com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection.lambda$getClosedConnection$0(ProxyConnection.java:515) ~[HikariCP-5.0.0.jar!/:na]
at com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection$$Lambda$718/0x00000000558ea900.invoke(Unknown Source) ~[na:na]
at com.sun.proxy.$Proxy105.prepareStatement(Unknown Source) ~[na:na]
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337) ~[HikariCP-5.0.0.jar!/:na]
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java) ~[HikariCP-5.0.0.jar!/:na]
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2122) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2059) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2037) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:956) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2868) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2850) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2682) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.Loader.list(Loader.java:2677) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:540) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1459) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.buildAndExecuteQuery(AbstractAuditQuery.java:106) ~[hibernate-envers-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery.getQueryResults(RevisionsOfEntityQuery.java:173) ~[hibernate-envers-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery.list(RevisionsOfEntityQuery.java:136) ~[hibernate-envers-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.getResultList(AbstractAuditQuery.java:112) ~[hibernate-envers-5.6.8.Final.jar!/:5.6.8.Final]
还有另一个堆栈跟踪:
com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 35,850,470 milliseconds ago. The last packet sent successfully to the server was 35,850,472 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-java-8.0.28.jar!/:8.0.28]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-java-8.0.28.jar!/:8.0.28]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.28.jar!/:8.0.28]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1009) ~[mysql-connector-java-8.0.28.jar!/:8.0.28]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-4.0.3.jar!/:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.3.jar!/:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.getResultSet(Loader.java:2322) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2075) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2037) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:956) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2868) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2850) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2682) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.Loader.list(Loader.java:2677) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:540) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1459) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617) ~[hibernate-core-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.buildAndExecuteQuery(AbstractAuditQuery.java:106) ~[hibernate-envers-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery.getQueryResults(RevisionsOfEntityQuery.java:173) ~[hibernate-envers-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery.list(RevisionsOfEntityQuery.java:136) ~[hibernate-envers-5.6.8.Final.jar!/:5.6.8.Final]
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.getResultList(AbstractAuditQuery.java:112) ~[hibernate-envers-5.6.8.Final.jar!/:5.6.8.Final]
已更新:
这是我的服务,它使用auditQuery
public List<Revision> getRevisions(Integer id) {
AuditQuery auditQuery = null;
List<Revision> revisionList = new ArrayList<Revision>();
//Find all modifications
try {
auditQuery = auditReader.createQuery()
.forRevisionsOfEntityWithChanges(MyEntity.class, true)
.addOrder(AuditEntity.revisionNumber().desc());
}
catch (Exception exception) {
log.error("Can not get revisions. Return empty list without revisions.");
log.error(exception.getMessage());
return new ArrayList<Revision>();
}
List<Object[]> result = auditQuery.getResultList();
最后一行是当我在连接关闭时收到错误时。
这是配置类
@Configuration
public class AuditConfiguration {
private final EntityManagerFactory entityManagerFactory;
AuditConfiguration(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
@Bean
AuditReader auditReader() {
return AuditReaderFactory.get(entityManagerFactory.createEntityManager());
}
}
最佳答案
根据您的堆栈跟踪,我想说根本原因是在您的应用程序中的某个地方。
我。以下设置对 hikari
连接轮询没有影响:
testOnBorrow : true
validationQuery : SELECT 1
这些设置对 Tomcat JDBC Connection Pool 有效。 ,请注意这些设置的配置前缀应为 spring.datasource.tomcat
。
如果您需要为hikari
连接池设置验证查询,则有效的配置设置为spring.datasource.hikari.connection-test-query
,但是在大多数情况下情况下不需要,而且 hikari
作者 is strongly discouraging from using this feature :
If your driver supports JDBC4 we strongly recommend not setting this property. This is for "legacy" drivers that do not support the JDBC4
Connection.isValid()
API. This is the query that will be executed just before a connection is given to you from the pool to validate that the connection to the database is still alive. Again, try running the pool without this property, HikariCP will log an error if your driver is not JDBC4 compliant to let you know. Default: none
二。你不应该使用 autoReconnect=true
as well :
Should the driver try to re-establish stale and/or dead connections? If enabled the driver will throw an exception for queries issued on a stale or dead connection, which belong to the current transaction, but will attempt reconnect before the next query issued on the connection in a new transaction. The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don't handle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead and stale connections properly. Alternatively, as a last option, investigate setting the MySQL server variable 'wait_timeout' to a high value, rather than the default of 8 hours.
III。仔细看看以下堆栈跟踪:
java.sql.SQLException: Connection is closed
at com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection.lambda$getClosedConnection$0(ProxyConnection.java:515) ~[HikariCP-5.0.0.jar!/:na]
at com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection$$Lambda$718/0x00000000558ea900.invoke(Unknown Source) ~[na:na]
at com.sun.proxy.$Proxy105.prepareStatement(Unknown Source) ~[na:na]
注意,com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection
类中抛出了异常,hikari
基于通过代理替换了真实的jdbc连接实例com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection
当 JDBC 连接时 gets closed或receives fatal error ,因此很明显您的应用程序在关闭后继续使用 JDBC 连接或出现 fatal error
更新。
好吧,现在很清楚发生了什么。配置如下:
@Configuration
public class AuditConfiguration {
private final EntityManagerFactory entityManagerFactory;
AuditConfiguration(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
@Bean
AuditReader auditReader() {
return AuditReaderFactory.get(entityManagerFactory.createEntityManager());
}
}
创建单个/应用程序范围的EntityManager
实例并将其绑定(bind)到AuditReader
的单个实例,这就是为什么你永远不会释放底层的JDBC连接到池并让那些愚蠢的错误。
快速修复方法是删除过早的优化并重写服务类,例如(这里我相信 EMF 由 spring
管理):
@Autowired
private EntityManager entityManager;
@Transactional
public List<Revision> getRevisions(Integer id) {
AuditReader auditReader = AuditReaderFactory.get(entityManager);
AuditQuery auditQuery = null;
List<Revision> revisionList = new ArrayList<Revision>();
关于java - 与 data-envers 的连接已关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75230651/