2013-04-14 2 views
0

Мне нужно выполнить семь отдельных процессов последовательно (один за другим). Данные хранятся в Mysql. Я думаю о следующих вариантах: Пожалуйста, поправьте меня, если я ошибаюсь, или если есть лучшее решение.Весенняя партия - цепочка процессоров

ТРЕБОВАНИЯМ:

  1. читать данные из БД, сделать семь процессов, наконец, написать обработанные данные в БД (datavalidation, calculation1, calculation2 ... и т.д.)..

  2. Необходимо обработать данные в кусках.

Мое решение и проблемы: данных следующим образом:

  1. Считывание данных с использованием JdbcCursorItemReader, потому что это лучшее выполнение дб читатель - Но, то SQL является очень сложным, так что я, возможно, придется рассмотрите пользовательский ItemReader, используя JdbcTemplate? что дает мне большую гибкость в обработке данных.

процесса:

  1. Определить семь шагов и ломти, обмениваться данными между шагами, используя DataBean. Но это не будет хорошей идеей, потому что процессы обработки данных в кусках и после каждого фрагмента сценарий step1 создаст новый набор данных в databean. Когда этот файл данных будет использоваться для других шагов, целостность данных будет проблемой.

  2. Использование StepExecutionContext для обмена данными между этапами. Но это может повлиять на производительность, поскольку это включает в себя репозиторий пакетных заданий.

  3. Определите только один шаг с помощью одного элемента ItemReader и цепочки процессов (семь процессов) и создайте один элемент ItemWriter, который записывает обработанные данные в БД. Но я не смогу управлять или контролировать каждый процесс, все будет за один шаг.

ответ

4

org.springframework.batch.item.support.CompositeItemProcessor является из компонента коробки из Spring Batch Framework, что поддержка будет ваше требование сродни вашей второй вариант. это позволит вам сделать следующее: - сохраняйте разделение в своем дизайне/решении для чтения из базы данных (itemreader) - сохраняйте разделение проблем и конфигурации каждого отдельного процессора - разрешить любому отдельному процессору «выключать» кусок, возвращая нуль, независимо от предыдущих процессов

CompositeItemProcessor выполняет итерацию по петле делегатов, поэтому он «похож» на шаблон действия. это очень полезно в сценарии вы описали и по-прежнему позволяет использовать преимущество чанки (исключение, повторить попытку, совершить политики и т.д.)

+0

Спасибо за ответ. – Nandan

+0

Что касается администрирования, какой подход был бы наиболее подходящим? отдельные шаги или один шаг с помощью составного процессора? – Nandan

+0

Отдельные шаги приводят к сложности при перезапуске в сценарии сбоя. Один шаг с CompositeItemProcessor означает, что все процессоры откатываются в случае сбоя. –

1

Предложений:

1) Считать данные с помощью JdbcCursorItemReader.

Все готовые компоненты являются хорошим выбором, поскольку они уже реализуют интерфейс ItemStream, который делает ваши шаги перезапущенными. Но, как вы уже упоминали, когда-то запрос просто для того, чтобы усложнить или, как и я, у вас уже есть служба или DAO, которые вы можете повторно использовать.

Я предлагаю вам использовать ItemReaderAdapter. Это позволяет настроить службу делегатов для вызова ваших данных.

<bean id="MyReader" class="xxx.adapters.MyItemReaderAdapter"> 
     <property name="targetObject" ref="AnExistingDao" /> 
     <property name="targetMethod" value="next" />   
    </bean> 

Обратите внимание, что targetMethod должен соблюдать договор считывания ItemReaders (возврат нуль, когда больше данных)

Если ваша работа не должна быть перезапускаемые, вы могли бы просто использовать класс: орг. springframework.batch.item.adapter.ItemReaderAdapter

Но если вам нужна ваша работа, чтобы быть перезапускаемыми, вы можете создать свой собственный ItemReaderAdapter как это:

public class MyItemReaderAdapter<T> extends AbstractMethodInvokingDelegator<T> implements ItemReader<T>, ItemStream { 




private long currentCount = 0; 

private final String CONTEXT_COUNT_KEY = "count"; 

/** 
* @return return value of the target method. 
*/ 
public T read() throws Exception { 

    super.setArguments(new Long[]{currentCount++}); 
    return invokeDelegateMethod(); 
} 
@Override 
public void open(ExecutionContext executionContext) 
     throws ItemStreamException { 
    currentCount = executionContext.getLong(CONTEXT_COUNT_KEY,0); 

} 


@Override 
public void update(ExecutionContext executionContext) throws ItemStreamException { 
    executionContext.putLong(CONTEXT_COUNT_KEY, currentCount); 
    log.info("Update Stream current count : " + currentCount); 
} 


@Override 
public void close() throws ItemStreamException { 
    // TODO Auto-generated method stub 

} 

} 

Поскольку вне коробки itemReaderAdapter не перезапускаемая, вы просто создать свой собственный, который реализует ItemStream

2) Что касается 7 шагов против 1 шаг.

Я бы пошел с 1 шагом с составным процессором на этом. вариант с 7 шагами вызовет проблемы только с ИМО.

1) 7 шагов databean: поэтому ваш писатель фиксирует данные в файле до шага 7 .. тогда шаг 7 писателя попытается зафиксировать реальную базу данных и ошибку стрелы !!! все потеряно, и пакет должен перезапустить с шага 1!

2) 7 шагов с контекстом: может быть лучше, так как у вас будет состояние, сохраненное в метаданных весенней партии. НО это не хорошая практика хранения больших данных в метаданных springBatch !!

3) это способ пойти ИМО. ;-)

Смежные вопросы