Spring batch JdbcPagingItemReader отсутствует записи un commit
Пакетный режим состоит из 4 шагов: 1. Выполнить несколько основных задач. 2. Извлечь записи из входной таблицы -> Процесс -> Из таблицы. 3. Проверить количество ошибок, проверить количество записей во входных и выходных таблицах. 4. вытащить записи из таблицы и обновить статус бизнес-таблиц.
У меня есть проблема, что количество записей в нашей таблице идет правильно, но когда шаг 4 полных записей имеет меньше записей. Поскольку я использую Oracle, я чувствую, что его фиксация не выполнена, когда записи извлекаются.
Пожалуйста, предложите, если кто-то сталкивается с подобной проблемой.
Конфигурация выглядит следующим образом:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util" xmlns:orcl="http://www.springframework.org/schema/data/orcl"
xmlns:batch="http://www.springframework.org/schema/batch"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/data/orcl
http://www.springframework.org/schema/data/orcl/spring-data-orcl-1.0.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-3.0.xsd ">
<context:component-scan base-package="com.test." />
<import resource="classpath:context-datasource.xml" />
<bean id="parameterSetter" class="com.test.helper.QueryParamSetter"
scope="step">
<constructor-arg value="#{jobParameters['fileName']}" />
</bean>
<bean id="pagingItemReader"
class="org.springframework.batch.item.database.JdbcPagingItemReader"
scope="step">
<property name="dataSource" ref="dataSource" />
<property name="queryProvider">
<bean
class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="selectClause" value="SELECT *" />
<property name="fromClause" value="from INPUT_TABLE" />
<property name="whereClause"
value="FILE_NAME= :fileName AND rownum < 3001" />
<property name="sortKey" value="INPIUT_STG_ID" />
</bean>
</property>
<property name="parameterValues">
<map>
<entry key="fileName" value="#{jobParameters['fileName']}" />
</map>
</property>
<property name="pageSize" value="100" />
<property name="rowMapper">
<bean class="com.test.InputVOMapper" />
</property>
</bean>
<bean id="postItemReader"
class="org.springframework.batch.item.database.JdbcPagingItemReader"
scope="step">
<property name="dataSource" ref="dataSource" />
<property name="queryProvider">
<bean
class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="selectClause" value="select *" />
<property name="fromClause" value="from OUTPUT_TABLE" />
<property name="whereClause"
value="FILE_NAME= :fileName AND TXN_ID IS NOT NULL AND FILE_DATA IS NOT NULL" />
<property name="sortKey" value="CREATE_DT" />
</bean>
</property>
<property name="parameterValues">
<map>
<entry key="fileName" value="#{jobParameters['fileName']}" />
</map>
</property>
<property name="pageSize" value="100" />
<property name="rowMapper">
<bean class="com.test.mapper.OutputVOMapper" />
</property>
</bean>
<!-- JobExecutionListener to perform business logic before and after the
job -->
<bean id="jobListener" class="com.test.SettlementJobListener">
<property name="templateDir" value="templates" />
</bean>
<bean id="processEventHelper" class="com.wdpr.payment.helper.ProcessEventHelper" />
<!-- ItemWriter which writes data to database -->
<bean id="errorWriter"
class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="UPDATE INPUT_TABLE SET ERR_CD=:batchErrorCode, ERR_DS=:batchErrorDesc WHERE PROC_ID=:rrn" />
<property name="itemSqlParameterSourceProvider">
<bean
class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
</property>
</bean>
<bean id="recordWriter"
class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="INSERT INTO OUTPUT_TABLE (CARD_SETTL_ID,TXN_ID,CREATE_DT,CREATE_PROC_ID,FILE_DATA,CLIENT_ID,FILE_NAME) values (:a,:b,:c,:d,:e,:f,:g)" />
<property name="itemSqlParameterSourceProvider">
<bean
class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
</property>
</bean>
<bean id="databaseItemWriter" class="com.test.SettlementDataWriter"
scope="step">
<property name="errorWriter" ref="errorWriter" />
<property name="recordWriter" ref="recordWriter" />
</bean>
<bean id="itemProcessor" class="com.test.SettlementDataProcessor"
scope="step" />
<bean id="preProcessor" class="com.test.PreProcessor" />
<!-- Step will need a transaction manager -->
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="statusItemWriter" class="com.test.StatusItemWriter" scope="step">
<property name="processorHelper" ref="processorHelper" />
</bean>
<bean id="errorCheck" class="com.test.ErrorCheckTasklet"
scope="step">
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="sql"
value="SELECT count(*) from INPUT_TABLE where FILE_NAME= ? AND ERR_CD IS NOT NULL" />
<property name="footerCount"
value="SELECT count(*) from OUTPUT_TABLE where FILE_NAME= ? AND FILE_DATA IS NOT NULL" />
<property name="countCheck"
value="SELECT count(*) from OUTPUT_TABLE where FILE_NAME= ? AND TXN_ID IS NOT NULL AND FILE_DATA IS NOT NULL" />
<!-- <property name="preparedStatementSetter" ref="parameterSetter" /> -->
<property name="recordWriter" ref="recordWriter" />
</bean>
<bean id="preProcessReader" class="com.test.PreProcessReader"
scope="step">
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="sql1"
value="select count(PROC_ID) from INPUT_TABLE where FILE_NAME=? AND rownum < 101" />
<property name="sql2"
value="select count(distinct(PROC_ID)) from INPUT_TABLE where FILE_NAME=? AND rownum < 101" />
<property name="preparedStatementSetter" ref="parameterSetter" />
</bean>
<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" >
<property name="concurrencyLimit" value="100" />
</bean>
<!-- Actual Job -->
<batch:job id="settelmentJob">
<batch:step id="step1" next="step2">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="preProcessReader" processor="preProcessor"
writer="recordWriter" commit-interval="1" />
</batch:tasklet>
</batch:step>
<batch:step id="step2" next="step3" >
<batch:tasklet transaction-manager="transactionManager"
task-executor="taskExecutor" throttle-limit="100" ><!-- throttle-limit="100" -->
<batch:chunk reader="pagingItemReader" writer="databaseItemWriter"
processor="itemProcessor" commit-interval="100" /> <!-- commit-interval="100" -->
</batch:tasklet>
</batch:step>
<batch:step id="step3" >
<batch:tasklet transaction-manager="transactionManager"
ref="errorCheck" >
</batch:tasklet>
</batch:step>
<batch:step id="step4">
<batch:tasklet transaction-manager="transactionManager"
task-executor="taskExecutor" throttle-limit="100" >
<batch:chunk reader="postItemReader" writer="statusItemWriter"
commit-interval="100" />
</batch:tasklet>
</batch:step>
<batch:listeners>
<batch:listener ref="jobListener" />
</batch:listeners>
</batch:job>
<!-- JobRepository and JobLauncher are configuration/setup classes -->
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
</bean>
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
Источник данных
bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="initialSize" value="30" />
<property name="maxIdle" value="10" />
<property name="validationQuery" value="select 1 from dual" />
<property name="maxTotal" value="50"></property>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="10000"/>
<property name="removeAbandonedOnBorrow" value="true"/>
2 ответа
Я обнаружил, что проблема была не в коммите, но в конфигурации jdbcpagination возвращается другой результат, чем в запросе. Я создал ниже вопрос.
JdbcPagingItemReader в пакете Spring не дает правильных результатов
Я считаю, что проблема в том, что вы используете ResourcelessTransactionManager
, Есть две проблемы с этим:
- Это означает, что вы на самом деле не используете транзакции (поскольку он не работает ни с какими ресурсами).
- Это означает, что Spring Batch не будет ждать завершения коммита, прежде чем продолжить, так как истинный коммит не вызывается.
Вы уже используете JobRepository на основе карты. Вы должны использовать TransactionManager для источника данных, над которым вы работаете с Oracle. Это исправит вашу проблему.