分区块步骤,只有第一个分区成功运行,其他分区显示ResultSet关闭错误



我正在从DB2表中读取数据并将其转储到文件中。我根据列中的值对步骤进行分区。如果column1值为"XYZ",它将进入一个分区,如果column1值是"ABC",则它将进入另一个分区。

问题是第一个分区执行正确,数据被写入文件,但对于第二个分区,我得到了"ResultSet is closed"错误。因此生成了2个线程,并执行两次查询。我确实得到了两个不同的结果集;然而,只有一个ResultSet被迭代,另一个线程会给出错误。

您会混淆reader属性分支和分区计划属性parameterForWhereClause,它们的值被替换为branch的每个分区值。

这样的东西会起作用,在JSL:中

<step id="StepID" start-limit="1">
        <chunk checkpoint-policy="item" item-count="10">
            <reader
                ref="ReaderClass">
                <properties >
                <property name="parameterForWhereClause" value="#{partitionPlan['branch']}"/>
                </properties>
            </reader>
            <writer
                ref="WriterClass">
                </writer>
        </chunk>
        <partition>
            <plan partitions="2" threads="2">
                <properties partition="0">
                    <property name="branch" value="XYZ"/>
                </properties>
                <properties partition="1">
                    <property name="branch" value="ABC"/>
                </properties>
            </plan>
        </partition>
    </step>

(我去掉了步骤级属性,因为它并不明显你真的在使用它。)

因此,理解这一点的方法是,Java工件的属性名称(如果您有一个@BatchProperty而没有name注释值,则它将是字段名称)将与JSL读取器属性名称匹配。因此,我将JSL读取器属性的名称更改为parameterForWhereClause以匹配您的字段。

由于读取器是分区级工件(对于分区步骤),它可以使用partitionPlan替换,这就是我所展示的为读取器的参数ForWhereClause属性提供值的内容。

发生此错误是因为您无法在多个线程中重用java.sql.ResultSetResultSet是事务性的,并且绑定到创建它的线程和事务。其他类型的JDBC资源(语句和连接)也是如此。唯一应该在线程之间共享的JDBC资源是DataSource。您还需要确保您正在关闭连接。在某些情况下,WebSphereApplicationServer可能能够为您关闭它们,我希望这就是导致"ResultSet is closed"错误的原因,但最佳做法是在使用完JDBC资源后立即关闭它们,并且永远不要跨线程缓存它们。在这种情况下,您将需要获得一个连接,并每次通过执行一个查询。应用服务器将通过池化Connection和缓存PreparedStatement来提供一些帮助。每次重新执行查询仍然会有开销,但这是无法解决的。

相关内容

  • 没有找到相关文章

最新更新