2012-04-17 91 views
0

我想完成的一个简单的任务:如何设置一个简单的多行ItemReader和配置批量操作的工作是可恢复?

  1. 读取包含分隔SQL查询的文本文件“;”。
  2. 在单独的事务中执行每个查询
  3. 能够从第一个失败的查询中重新启动/恢复执行。

我试着用弹簧批次做到这一点(版本2.1.8.RELEASE) 我所面临的问题如下:。

我没有配置简单外的the-框ItemReader,它会读取几行直到“;”并传递给ItemWriter之前它们聚集。

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

问题1:为什么我需要一个FieldSetMapperprototypeBeanName设置为一个复杂的对象,如果我要的是它传递给ItemWriter之前,在一个单一的String所有行追加?当我配置fieldSetMapper的财产prototypeBeanName来指代java.lang.String我得到一个异常说,名称的数量不等于值的数量。我调试的弹簧 - 分批代码,发现有映射到单个名称2个值:名称 =%SOME_NAME% = {%MY_SQL_QUERY%,“;”}和异常是由AbstractLineTokenizer.tokenize()线123

抛出

问题2:通过使用开箱即用的弹簧批次ItemReaders是否可以实现线路集合,如何配置?我在配置中错过了什么吗? (见下文)

配置:

<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个成员的简单类:SQL(用于查询)和eol(对于 ';')它是用来克服形势的AbstractItemReader返回所有排队到分离器(作为String),并在分离器(在我的情况“;”)作为values

问题3:如果运行仅使用一个单一的步骤读写器方法的SQL查询的大部分工作,中间我怎么能恢复/失败重新从第一个任务失败的查询?我应该这样做编程的最后一次运行分析或者可以在由作业步的上下文配置和相关外的开箱弹簧批次豆可以实现吗?

+0

使用[PassThroughFieldSetMapper](http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/item/file/mapping/PassThroughFieldSetMapper.html)查看。它只是返回fieldSet,允许你直接在你的ItemProcessor/ItemWriters中使用它。 – 2012-04-17 12:56:15

回答

0

问题3,我会做一些事情

  • 在项目读者可以传递一个属性,如“saveState和”真
  • 集“提交间隔”,以一个合适的值
  • 配置Spring Batch的数据库,因此它可以保存状态

如果以上设置,而不要使用“未来”为作业实例,它会恢复你离开的地方!