Шаг портированного раздела, только первый раздел работает успешно, остальные показывают, что 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
, У вас все еще будут накладные расходы на повторное выполнение запроса каждый раз, но нет никакого способа обойти это.