【问题标题】:SQLException: I/O Error: Read timed outSQLException:I/O 错误:读取超时
【发布时间】:2018-08-16 21:37:04
【问题描述】:

我有一个连接到 SQL Server 数据库的 Java Spring 应用程序。

连接设置为:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="net.sourceforge.jtds.jdbc.Driver" />
        <property name="jdbcUrl"
            value="jdbc:jtds:sqlserver://${db.host}:1433/TestDB" />
        <property name="user" value="${db.user}" />
        <property name="password" value="${db.pass}" />

        <!-- these are connection pool properties for C3P0 -->
        <property name="minPoolSize" value="10" />
        <property name="maxPoolSize" value="100" />
        <property name="acquireIncrement" value="5"/>
        <property name="maxIdleTime" value="30000" />
    </bean>

一切正常,但有时我收到以下错误:

Could not open JDBC Connection for the transaction; nested exception is java.sql.SQLException: I/O Error: Read timed out

我搜索了很多,但找不到任何线索、任何想法或帮助?

我正在使用

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="sqlSessionFactory" />
</bean>

在我的spring-config xml 中获取我的sqlSession,并在我使用的 DAO 中:

@Autowired  
SqlSession sqlSession;

然后我执行我想要的查询。有没有可能是因为连接没有关闭而存在这个错误?

【问题讨论】:

  • 请发布完整的异常堆栈跟踪。另外,您确定 db.host 的值正确,并且 SQL Server 实际上正在侦听该主机上的端口 1433?
  • 在 server.xml 中保留连接池属性。那是适合他们的地方。
  • @YatiSawhney OP 正在使用 spring,在 spring config 中配置它是完全可以接受的。
  • @MarkRotteveel 抱歉,我没有堆栈跟踪的副本,并且此错误还没有再次发生,是的,db.host 和端口号的值是正确的,因为错误发生在应用程序已经在运行
  • 在这种情况下,这可能只是网络问题,或者由于不活动而导致连接中断。我不认为你需要担心它。如果它发生得更频繁,您可能需要减少maxIdleTime(当前值 30000 秒意味着允许连接在池中空闲(未使用)超过 8 小时,这有点多),并检查服务器端的超时配置。

标签: java sql-server spring jdbc


【解决方案1】:

在我的情况下,当每晚的数据库备份作业触发时,连接会断开。我也在使用 jtds/sql-server。这是我为修复它所做的:

  • 创建/设置运行状况检查 cron 作业,该作业在应用程序中执行简单查询,例如简短的 select from。每 10 分钟左右调用一次并记录结果。它会为您提供有关何时以及为何发生这种情况的一些反馈。
  • 减少配置中的空闲时间参数 (maxIdleTime),以便自动丢弃旧连接。

请记住,如果您不更改 maxIdleTime 并保持多个连接处于打开状态,即使您正在使用运行状况检查功能,其中一些连接可能仍处于不良状态。引用c3p0 documentation:

默认情况下,连接池永远不会过期。如果您希望连接随着时间的推移而过期以保持“新鲜度”,请设置 maxIdleTime 和/或 maxConnectionAge。 maxIdleTime 定义在从池中剔除之前应允许连接未使用的秒数。 maxConnectionAge 强制池剔除从数据库获取的任何连接数超过过去设置的秒数。

另一种设置健康检查调用的方法是使用idleConnectionTestPeriod 参数。另请查看此answer,它可以为您提供有关如何设置的更多想法。

【讨论】:

    猜你喜欢
    • 2016-04-03
    • 2021-09-11
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 2014-03-07
    • 2019-05-25
    相关资源
    最近更新 更多