繁体   English   中英

PostgreSQL 抛出“连接已被放弃”->“发送到后端时发生 I/O 错误”

[英]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 在后端断开连接时抛出的。

  1. 尝试将驱动更新到最新版本: 9.4-1202
  2. postgresql.conf尝试设置: log_statement = 'all' ,以查看所有语句日志数据,以便您更好地了解导致问题的原因。

这很可能是因为您的外部方法正在使用事务传播 NOT_SUPPORTED。 此配置将暂停其他打开的事务,并且在处理大量数据时,这些暂停的事务可能会发生超时。

我知道你说这个方法是在没有活跃交易的情况下执行的,但你完全确定吗? 单一结果错误表明正在执行一个选择语句。

您可以尝试另一种适合您要求的传播配置,看看它是否有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM