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

Db2 分区块步骤,只有第一个分区成功运行,其他分区显示ResultSet已关闭错误,db2,jsr352,java-batch,Db2,Jsr352,Java Batch,我从DB2表中读取数据并将其转储到文件中。我正在根据列中的值对步骤进行分区。如果 column1的值是“XYZ”,它将进入一个分区,如果column1的值是“ABC”,它将进入另一个分区 问题是第一个分区执行正确,数据写入文件,但对于第二个分区,我得到了“ResultSet is closed”错误。因此产生了两个线程,并执行了两次查询。我得到了两个不同的结果集;但是,只有一个结果集被迭代,另一个线程给出了错误。您混淆了reader属性branch和分区计划属性parameterForWhere

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


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

您混淆了reader属性branch和分区计划属性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>

(我去掉了step-level属性,因为不清楚您是否真的在使用它。)

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


由于读取器是分区级工件(对于分区步骤),因此它可以使用分区计划替换,这就是我显示的为读卡器的parameterForWhereClause属性提供值的内容。

您将在读卡器属性分支和分区计划属性parameterForWhereClause之间产生混淆,后者的值被替换为每个分区的值分支机构

在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>

(我去掉了step-level属性,因为不清楚您是否真的在使用它。)

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


由于读卡器是一个分区级工件(对于分区步骤),它可以使用分区计划替换,这就是我显示的为读卡器的parameterForWhereClause属性提供值的内容。

发生错误的原因是您无法跨多个线程重用
java.sql.ResultSet
ResultSet
是事务性的,并且与创建它的线程和事务相关联。其他类型的JDBC资源(语句和连接)也是如此。应该跨线程共享的唯一JDBC资源是
数据源
。您还需要确保正在关闭连接。在某些情况下,websphereapplicationserver可能能够为您关闭它们,我希望这里发生的情况会导致“ResultSet is closed”错误,但最佳做法是在处理完JDBC资源后立即关闭它们,并且从不跨线程缓存它们。在这种情况下,您将需要获得一个连接,并每次通过执行一个查询。应用程序服务器将通过汇集
连接
和缓存
PreparedStatement
有所帮助。每次重新执行查询的开销仍然存在,但没有办法解决。

发生错误的原因是无法跨多个线程重用
java.sql.ResultSet
ResultSet
是事务性的,并且与创建它的线程和事务相关联。其他类型的JDBC资源(语句和连接)也是如此。应该跨线程共享的唯一JDBC资源是
数据源
。您还需要确保正在关闭连接。在某些情况下,websphereapplicationserver可能能够为您关闭它们,我希望这里发生的情况会导致“ResultSet is closed”错误,但最佳做法是在处理完JDBC资源后立即关闭它们,并且从不跨线程缓存它们。在这种情况下,您将需要获得一个连接,并每次通过执行一个查询。应用程序服务器将通过汇集
连接
和缓存
PreparedStatement
有所帮助。每次重新执行查询的开销仍然存在,但没有办法解决。

好的,所以我只是想用parameterforwhere子句代替branch,显然我做得不好(我只是想让代码通用)。这不是问题所在。很抱歉我现在已经正确地编辑了代码(希望如此)。我确信我能够正确地注入属性。问题仍然是第一个分区执行正确,数据写入文件,但对于第二个分区,我得到了“ResultSet is closed”错误。因此产生了两个线程,查询执行了两次,我得到了两个不同的结果集,但是只有一个o