如何设置简单的多行ItemReader并将批量操作作业配置为可恢复?

时间:2012-04-17 07:50:15

标签: java spring spring-batch

我正在努力完成一项简单的任务:

  1. 读取包含以“;”分隔的SQL查询的文本文件。
  2. 在单独的交易中执行每个查询
  3. 能够从第一个失败的查询重启/恢复执行。
  4. 我尝试使用spring-batch执行此操作。(版本2.1.8.RELEASE) 我面临的问题如下:

    我无法配置一个简单的开箱即用的ItemReader,它会读取几行直到“;”并在传递给ItemWriter之前聚合它们。

    我不需要FieldSetMapper我根本就没有字段。我的输入是一个包含SQL查询的文本文件。每个查询可以占用1行或更多行,查询以分号分隔。似乎在没有为复杂bean指定LineMapper的情况下在ItemReader内定义FieldSetMapper是不可能的(我试图将BeanWrapperFieldSetMapper设置为映射到java.lang.String但由于下面描述的异常而失败了。

    问题1:为什么我需要FieldSetMapperprototypeBeanName设置为复杂对象,如果我想要的是将所有行追加到单个StringItemWriter 1}}在传递给fieldSetMapper之前?当我配置prototypeBeanName的属性java.lang.String以引用AbstractLineTokenizer.tokenize()时,我得到一个异常,说明名称的数量不等于值的数量。我调试了弹簧批处理代码,发现有2个值映射到一个名称:名称 =%SOME_NAME% = {%MY_SQL_QUERY%,“;”} ItemReaders第123行抛出了异常

    问题2 :是否可以通过使用开箱即用的弹簧批<bean id="basicParamsIncrementer" class="com.linking.core.exec.control.BasicJobParamsIncrementer" /> <batch:job id="rwBatchJob" restartable="true" incrementer="basicParamsIncrementer"> <batch:step id="processBatchStep"> <batch:tasklet transaction-manager="transactionManager" > <batch:chunk reader="batchFileItemReader" writer="sqlBatchFileWriter" commit-interval="1" /> </batch:tasklet> </batch:step> </batch:job> <bean id="batchFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader"> <property name="resource" value="classpath:/bat.sql.txt" /> <property name="recordSeparatorPolicy" ref="separatorPolicy" /> <property name="lineMapper"> <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"> <property name="lineTokenizer" ref="sqlTokenizer" /> <property name="fieldSetMapper" ref="sqlFieldSetMapper" /> </bean> </property> </bean> <bean id="separatorPolicy" class="com.linking.core.SemiColonRecordSeparatorPolicy" /> <bean id="sqlTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"> <property name="delimiter" value=";" /> <property name="names" value="sql,eol"/> </bean> <bean id="sqlFieldSetMapper" class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper"> <property name="prototypeBeanName" value="sql" /> </bean> <bean id="sql" class="com.linking.core.model.SQL" scope="prototype" /> 来实现线路聚合,如果是,需要如何配置?我的配置中是否遗漏了什么? (见下文)

    配置:

    com.linking.core.model.SQL

    String是一个简单的类,有2个eol类型的成员:sql(用于查询)和AbstractItemReader(用于';')它用于克服这种情况String将所有行返回到分隔符(作为values),并将分隔符(在我的情况下为“;”)返回为{{1}}。

    问题3:如果仅使用单步读写器方法运行大量SQL查询的作业在中间失败,如何从第1个失败的查询中恢复/重新启动作业?我应该通过分析最后一次运行来编程,还是可以通过作业步骤的上下文配置和相关的开箱即用弹簧批量bean来实现?

1 个答案:

答案 0 :(得分:0)

对于问题3,我会做几件事

  • 在项目阅读器中,您可以将“saveState”等属性传递给true
  • 将“commit-interval”设置为合适的值
  • 配置Spring批处理DB,以便保存状态

如果设置了以上所有内容,并且您没有对作业实例使用“next”,它将从您离开的地方恢复!