【问题标题】:Unexpected ResultSet is closed exception at Spring web application意外的 ResultSet 是 Spring Web 应用程序中的关闭异常
【发布时间】:2011-07-30 08:26:02
【问题描述】:

我们有一个 spring bean,它在启动时从 Postgresql (8.4) 数据库加载应用程序消息。 Bean 定义如下:

代码非常简单:

get a connection (we are using a dbcp pool)
Create a statement (plain jdbc, nothing special)
execute the query, get the result set
while(resultSet.next())){
    cacheMap.put(resultSet.getString("column1"), resultSet.getString("column2"));       
}

代码有时会在应用程序启动时在 while 循环内引发 ResultSet is closed 异常。 它使用 Postgresql 8.4.2 可以正常工作,没有任何异常,但在使用 Postgresql 8.4.8 时大多数时间(并非总是)抛出异常。
我们在运行 windows 7 或 2008 服务器、Tomcat 6.0.32、最新版本的 java 1.6 的 4 台不同计算机上对其进行了测试,所有数据库服务器都在同一台机器上运行。 结果集包含大约 8000 行(两列;字符变化(200)和字符变化(1000))。 这里有什么问题?

  • 在我们处理完结果集之前,池是否可能正在关闭连接或重新使用它?
  • 或者它可能与数据库版本有关?

顺便说一下,我们更改了代码以在第一次使用消息而不是应用程序启动时加载消息,并且它工作正常。因此,只有在启动时调用代码时才会引发此异常,使用 init 方法。

提前致谢

【问题讨论】:

    标签: java spring jdbc


    【解决方案1】:

    我最初的想法是,您可能在完全初始化之前使用了 Spring 容器 bean。这有时会导致不一致的行为(当有配置更改或库更改时,事情可能不会以相同的顺序初始化)。您的最后一段还指出了依赖项初始化问题。

    Spring 使用 ref 连接来决定应该首先初始化哪些 bean。但是,如果您的 init 方法访问容器 bean(而不是使用注入的 bean),Spring 不知道这一点,您可能正在访问一个已构建但尚未初始化的 bean。缓存和静态初始化器似乎是这种悲伤的典型候选者。

    您将缓存构建活动移至构建 Spring 容器之后的某个时间的解决方案对我来说似乎是一个很好的解决方案。如果是依赖初始化问题,你可以猜到哪个 bean 不完整(比如连接池),你可以在 bean 配置中使用“depends-on”来强制初始化另一个 bean。

    如果这是一个初始化问题,那么我希望当你得到“结果集关闭”异常时,它总是在 while(resultSet.next())) 语句的第一次命中,你什么都没有在您的缓存中。要么事情没有正确初始化并且它立即失败,或者事情确实正确初始化并且你的缓存填充了。如果缓存被部分填充,并且在读取结果集的过程中发生了结果集错误,那么整个初始化理论就不再有意义了。

    【讨论】:

    • 感谢您的回答。我们只使用 spring 管理的 bean。结果集关闭异常不会在第一个结果时抛出。缓存被部分填充。例如,如果我们通常有 8k 行,则在处理 2k 行左右(不是实际数字)后抛出异常。不知何故,结果集,我认为语句在循环期间被关闭。文档说,如果在同一个连接上执行另一个查询,则该语句将关闭。也许连接池正在将连接交给另一个执行另一个查询的线程。但这种情况对我来说没有意义。
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2022-08-13
    • 1970-01-01
    • 2013-04-03
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多