【问题标题】:Connection closed error while executing query with Spring JDBC Template使用 Spring JDBC 模板执行查询时出现连接关闭错误
【发布时间】:2016-08-31 08:01:28
【问题描述】:

我正在使用 Spring JDBC 模板来查询 SQL Server db。我有一个计划任务配置为每周执行一次,下面是实现:

@Autowired
private JdbcTemplate jdbcTemplate;

public void importData(){

    try{
        logger.debug("Importing Data");
        jdbcTemplate.query(...) // Fails
     catch(DataAccessException e){
        //Log the error
     }
}

执行任务时(即每周一次),我收到以下异常:

org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Invalid state, the Connection object is closed.
        at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:305)
        at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:329)
        at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:214)
        at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:134)
        at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:97)
        at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:695)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:727)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:737)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:787)

下面是驱动类:

spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver

我猜如果 Spring(或 jdbc 驱动程序)在配置的时间内空闲,它会关闭连接。查看“查询”方法的实现,似乎它没有创建新的连接。在这种情况下,我是否需要使用其他方法(例如execute)?

【问题讨论】:

  • 你的连接池应该处理这个问题。你有一个连接池,对吧?
  • 我正在使用带有 Jetty 的 Spring Boot,因此根据本文档 (docs.spring.io/spring-boot/docs/current/reference/html/…) 它应该使用 Hikari 连接池?
  • 我相信只有在你的类路径中包含 Hikari 时。不确定它默认使用什么。
  • 对了!我将删除jetty依赖并尝试使用tomcat使tomcat连接池可用,看看是否能解决问题。
  • 更换一个 Web 服务器来改变 JDBC 连接池......听起来很明智。

标签: java sql-server spring spring-jdbc


【解决方案1】:

关闭连接的不是 Spring,而是关闭它的数据库,如果一段时间不活动。或者可能是由于网络故障。

任何连接池都可以在将连接提供给请求它的数据源之前对其进行测试。通常它是通过测试查询完成的。

所以检查连接池是否配置正确。

【讨论】:

  • 我正在使用 Spring boot,因此,它应该管理连接池吗?我启用了以下属性:spring.datasource.urlspring.datasource.usernamespring.datasource.passwordspring.datasource.driver-class-name。看看我是否也需要配置连接池类型。
【解决方案2】:

在您的 dispatcher-servlet.xml 中添加以下行:

<context:mbean-export registration="ignoreExisting" />

或者,如果你使用注解,添加:

@EnableMBeanExport(registration=RegistrationPolicy.IGNORE_EXISTING)

或者,您可以在资源中添加 server.xml(如果是 tomcat)singleton="false"

<GlobalNamingResources>
  <Resource singleton="false" ..... />
</GlobalNamingResources>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 2014-08-27
    • 2011-06-26
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多