在 (Liberty) Batch 块步骤中,从该步骤之前发出的数据库查询中滚动 ResultSet 时获取 "ResultSet is closed"

In a (Liberty) Batch chunk step, getting "ResultSet is closed" when scrolling through ResultSet from database query issued earlier in the step

我正在从 DB2 table 读取数据并将其转储到一个文件中。

我在块侦听器的 beforeChunk() 中执行我的简单 select 查询,并使用步骤上下文在 itemreader 中获取它。

在块中,我将检查点策略设置为 item,将 itemcount 设置为 5。

输出的是前5条记录被反复读写

在这个 sample java batch code from IBM's site 中,他们在查询中有开始和结束参数。

查询中是否需要包含开始和结束参数? 有没有其他方法可以确保当查询再次 运行 时它读取下一个数据块而不是一次又一次地读取同一个数据块?

我在 WebSphere Liberty 上使用 IBM 的 JSR 352 实现

尝试配置数据源以使用 不可共享 连接。

如果您关注此示例,您会发现它使用较旧的部署描述符 XML 文件。您可以编辑 batch-bonuspayout-application/src/main/webapp/WEB-INF/web.xml 以添加行:

<res-sharing-scope>Unshareable</res-sharing-scope>

所以完整的你有:

<web-app id="BonusPayout" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
  <display-name>BonusPayout</display-name>
  <description>This is the BonusPayout sample.</description>
  <resource-ref>
    <description>Bonus Payout DS</description>
    <res-ref-name>jdbc/BonusPayoutDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Unshareable</res-sharing-scope>
  </resource-ref>
</web-app>

这也可以使用较新的 @Resource 注释来完成,但如果您已经切换到该注释,那么您也会知道如何在其中应用这一点。

进行此更改后,位于 java:comp/env/jdbc/BonusPayoutDS 位置的现有 JNDI 查找现在将使用非共享连接,并且不会关闭 ResultSet在每个区块交易结束时。

WebSphere Application Server 传统文档中间接记录了此行为 here。 (我在 Liberty 文档中没有看到它,在某些情况下,Liberty 中的行为基本相同,并且 Liberty 中没有单独记录主题。)对于批处理用户来说有点间接。也很难完全描述,因为正如文档所说,确切的行为因数据库和 JDBC 提供商而异。但这应该适用于 DB2。

更新: 在较新的(自 17.0.0.1 起)版本的 Liberty 中,可以获得不可共享的连接 不需要使用资源通过使用 enableSharingForDirectLookups 属性配置 connectionManager 进行参考,例如:

<connectionManager ...  enableSharingForDirectLookups="false"/>