关于Spring Batch Chunk Behavior的澄清

时间:2015-08-12 13:17:50

标签: java spring-batch batch-processing jmstemplate

我们正在使用Spring Batch Chunk从JMS目标读取消息并写入平面文件。在这方面,我们有以下观察,

  1. 如果消息代理在读取器读取消息并且未达到提交计数时关闭,则到目前为止读取的消息数将被传递给Writer,然后批处理将进入FAILED状态。这是Chunk的默认行为吗?

  2. 如果第1点的答案为YES,我们如何确保不将此部分块发送给Writer。 (为了给出这个问题的更多背景知识,我们在JMS模板中进行了JMS会话处理,因此当块无法读取等于提交计数的完整数量的消息时,部分块中读取的所有消息都将回滚到JMS目标,即将相同的部分块写入文件。当我们重新启动批处理作业时,这会导致文件中出现重复。)

  3. 非常感谢任何帮助。

    修改

    配置如下所示,

    组块:

    <batch:step id="step-1" next="step-2">
        <batch:tasklet allow-start-if-complete="false">
            <batch:chunk reader="jms-reader-1-1" writer="file-writer-1-1" commit-interval="1000">
        </batch:chunk>
    </batch:step>
    

    作家(平面文件):

    <bean scope="step" class="o.s.b.i.f.FlatFileItemWriter" id="file-writer-1-1">
        <property name="resource" value="file:#{T(com.test.core.BatchConfiguration).BATCH_VFS_LOCAL_TEMP_LOCATION}/#{T(com.test.utils.ThreadContextUtils).getJobInstanceIdAsString()}/AssetMesage"/>
        <property name="lineAggregator">
            <bean class="o.s.b.i.f.t.DelimitedLineAggregator">
                <property name="delimiter" value=","/>
                <property name="fieldExtractor">
                    <bean class="o.s.b.i.f.t.BeanWrapperFieldExtractor">
                        <property name="names" value="assetId,assetName,assetDesc"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
    

    读者(JMS):

    <bean scope="step" class="com.test.runtime.impl.item.readers.JMSItemReader" id="jms-reader-1-1">
        <property name="adapter">
            <bean class="com.test.adapter.impl.JMSAdapter">
                <property name="resource" ref="JMS.vmsmartbatch02_Regression"/>
                <property name="retryerId" value="JMS.vmsmartbatch02_Regression-retryer"/>
            </bean>
        </property>
        <property name="destination" value="#{jobParameters[source1jmsdestination] != null ? jobParameters[source1jmsdestination] : &quot;sourceTopic&quot;}"/><property name="durableSubscriberName" value="sourceTopicDS"/><property name="destinationType" value="Topic"/>
        <property name="ackMode" value="#{T(javax.jms.Session).CLIENT_ACKNOWLEDGE}"/>
        <property name="maxMessageCount" value="2000"/>
    </bean>
    

    编辑2

    下面是我正在使用的核心阅读器逻辑,

    阅读器

        public Object read() throws Exception, UnexpectedInputException,
                    ParseException, NonTransientResourceException {
                Object item = null;
                try {
                    if(ackMode != 0 && ackMode >= 1  && ackMode <= 3){
                        adapter.getResource().setSessionAcknowledgeMode(ackMode);
                    }
    
                    if(maxMessageCount > 0){
                        ThreadContextUtils.addToExecutionContext("maxMessageCount", maxMessageCount);
      if(ThreadContextUtils.getExecutionContext().containsKey("readMessageCount")) {
                            readMessageCount = ThreadContextUtils.getExecutionContext().getInt("readMessageCount");
                        }
                    }
                    if (TOPIC_KEY.equalsIgnoreCase(destinationType)
                            && durableSubscriberName != null) {
                        item = (Object) adapter.invoke(REC_DS_AND_CONVERT_SELECTED,
                                OBJECT_CLASS, destination, durableSubscriberName,
                                receiveTimeout, filter == null ? "" : filter);
                    } else {
                        item = (Object) adapter.invoke(REC_AND_CONVERT_SELECTED,
                                OBJECT_CLASS, destination,
                                receiveTimeout <= 0 ? adapter.getResource()
                                        .getReceiveTimeout() : receiveTimeout,
                                (filter == null ? "" : filter));
                    }   
                    if(maxMessageCount > 0){
                     if( item !=null){
                          readMessageCount++;
                        ThreadContextUtils.addToExecutionContext("readMessageCount", readMessageCount);
                     }
                    }
                    return item;
                } finally {
    
                }
            }
    

0 个答案:

没有答案