![](/img/trans.png)
[英]Java PostgreSQL error on large query: An I/O error occurred while sending to the backend
[英]PostgreSQL throws "Connection has been abandoned" -> "An I/O error occurred while sending to the backend"
我知道有很多关于废弃连接的话题,但是我无法弄清楚我的问题是什么,所以我真的希望得到一些帮助。
我有一个带有 Spring 的 Java 应用程序,它从外部服务中获取一些数据,并尝试将其保存在数据库中。
我有以下 JDBC 池配置
<bean id="dataSource"
class="org.apache.tomcat.jdbc.pool.DataSource"
p:initialSize="2"
p:minIdle="10"
p:maxIdle="50"
p:maxActive="100"
p:maxWait="15000"
p:jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"
p:removeAbandoned="true"
p:removeAbandonedTimeout="60"
p:logAbandoned="true"
p:testOnBorrow="true"
p:testOnReturn="true"
p:testWhileIdle="true"
p:useEquals="false"
p:fairQueue="false"
p:timeBetweenEvictionRunsMillis="300000"
p:minEvictableIdleTimeMillis="300000"
p:validationInterval="10000"
p:validationQuery="SELECT 1">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
这是典型的 Spring env,在我的服务中,我有以下方法
@Autowired
private TransactionalWrapper wrapper;
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void reconcileAllEvents(Date from, Date to) {
for (Event event : eventService.reconcile(from, to)) {
transactionalWrapper.reconcile(event);
}
}
这是我在TransactionalWrapper
@Service
public class TransactionalWrapperImpl implements TransactionalWrapper {
@Autowired
private EventRepository eventRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void reconcile(Event event) {
try {
eventRepository.save(event);
} catch (Exception e) {
LOG.warn("Failed to handle event {}", event, e);
}
}
}
有一个夜间作业运行,每次大约有大约 10K 个事件。 我已经检查过在reconcileAllEvents()
中没有活动事务,并且在TransactionalWrapperImpl.reconcile()
为每个event
创建并提交了新事务。
问题是我不时遇到以下异常
Sep 10, 2015 5:25:57 PM org.apache.tomcat.jdbc.pool.ConnectionPool abandon
WARNING: Connection has been abandoned PooledConnection[org.postgresql.jdbc4.Jdbc4Connection@3eb948ed]:java.lang.Exception
at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1063)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:780)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:619)
at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:188)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:128)
at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:70)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:301)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:157)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1351)
at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:59)
at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:67)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:110)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:420)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:257)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
在这个之后还有另一个
10 Sep 2015 17:25:57,591 WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 08006
10 Sep 2015 17:25:57,592 ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - An I/O error occurred while sending to the backend.
javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: could not extract ResultSet
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:316)
at com.mysema.query.jpa.impl.AbstractJPAQuery.getSingleResult(AbstractJPAQuery.java:219)
at com.mysema.query.jpa.impl.AbstractJPAQuery.uniqueResult(AbstractJPAQuery.java:295)
at com.mysema.query.jpa.impl.AbstractJPAQuery.uniqueResult(AbstractJPAQuery.java:281)
at com.mysema.query.support.ProjectableQuery.singleResult(ProjectableQuery.java:75)
我检查了几次配置,没有发现任何错误或需要批准的内容,并且一直崩溃并且事件没有被保存。 请注意,异常后它会继续以正常方式保存其余事件。
任何想法配置有什么问题,以及如何处理这个问题?
这通常是 PostgreSQL 在后端断开连接时抛出的。
postgresql.conf
尝试设置: log_statement = 'all'
,以查看所有语句日志数据,以便您更好地了解导致问题的原因。这很可能是因为您的外部方法正在使用事务传播 NOT_SUPPORTED。 此配置将暂停其他打开的事务,并且在处理大量数据时,这些暂停的事务可能会发生超时。
我知道你说这个方法是在没有活跃交易的情况下执行的,但你完全确定吗? 单一结果错误表明正在执行一个选择语句。
您可以尝试另一种适合您要求的传播配置,看看它是否有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.