Шаг портированного раздела, только первый раздел работает успешно, остальные показывают, что ResultSet закрыт. Ошибка

Я читаю данные из таблицы DB2 и выгружаю их в файл. Я делю шаг на основе значений в столбце. То есть, если значением column1 является "XYZ", оно будет идти в одном разделе, а если значением column1 является "ABC", оно будет идти в другом.

Проблема в том, что первый раздел выполняется правильно, и данные записываются в файл, но для второго раздела я получаю сообщение об ошибке "ResultSet is closed". Таким образом, создаются 2 потока, и запрос выполняется дважды. Я получаю 2 разных набора результатов; однако повторяется только один из ResultSet, другой поток выдает ошибку.

2 ответа

Вы путаетесь между ветвью свойства считывателя и параметром свойства плана раздела ForWhereClause, значение которого подставляется в значение для каждого раздела для ветви.

Примерно так будет работать в 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 без значения аннотации имени) будет соответствовать имени свойства считывателя JSL. Поэтому я изменил имя свойства читателя JSL на parameterForWhereClause, чтобы оно соответствовало вашему полю.

Поскольку считыватель является артефактом уровня раздела (для этапа разбиения), он может использовать подстановку partitionPlan, что я и показываю, предоставляя значение для свойства parameterForWhereClause считывателя.

Ошибка происходит потому, что вы не можете использовать java.sql.ResultSet через несколько потоков. ResultSet является транзакционным и привязан к потоку и транзакции, в которой он был создан. Это также относится и к другим типам ресурсов JDBC (операторы и соединения). Единственный ресурс JDBC, который должен быть разделен между потоками, это DataSource, Вам также необходимо убедиться, что вы закрываете Connections. В некоторых случаях WebSphere Application Server может закрыть их для вас, и я ожидаю, что именно так и происходит, что приводит к ошибке "ResultSet is closed", но лучше всего закрыть ресурсы JDBC, как только вы закончите с ними и никогда не кэшируйте их между потоками. В этом случае вам нужно будет получить соединение и каждый раз выполнять запрос. Сервер приложений поможет несколько, объединив Connection и кеширование PreparedStatement, У вас все еще будут накладные расходы на повторное выполнение запроса каждый раз, но нет никакого способа обойти это.

Другие вопросы по тегам