2013-06-17 2 views
13

У меня есть прямое требование, в котором мне нужно прочитать список элементов (из БД), и вам нужно обработать элементы и после их обработки, он должен быть обновлен в БД ,Решающий шаг весны, Tasklet или Chunks

Я подумываю использовать весенний пакетный чанк с устройством чтения, процессором и писателем. Мой читатель вернет один элемент за раз из списка и отправит его на процессор, и как только обработка закончится, он вернется в Writer, где он обновит базу данных

Возможно, это может быть многопоточность позже с некоторой стоимостью синхронизации в этих методах ,

Здесь я предвижу несколько проблем.

  1. Количество элементов, подлежащих обработке, может быть больше. Может быть в 10 000 или даже больше.
  2. В процессоре требуется логический расчет. следовательно, обрабатывает 1 элемент за раз. не уверен в производительности, даже если он многопоточен с 10 потоками.
  3. Writer может обновлять результаты в БД для этого обработанного элемента. Не знаете, как выполнять пакетные обновления, потому что он всегда имеет только один элемент, обработанный и готовый.

Этот подход подходит для такого рода usecase или что-то еще лучше? Есть ли какой-либо другой способ обработки кучу элементов при одном вызове считывателя, процессор & writer? если это так, мне нужно создать какой-то механизм, где я извлекаю 10 элементов из списка и передаю их процессору? Кажется, что автор обновляет каждую запись, поскольку она приходит, пакетные обновления имеют смысл только в том случае, если писатель получает кучу обработанных элементов. любое предложение?

Пожалуйста, бросьте некоторые огни на этот дизайн для лучшей производительности.

Спасибо,

ответ

13

Spring Batch является идеальным инструментом, чтобы сделать то, что вам нужно.

Шаг, ориентированный на блок, позволяет настроить количество элементов, которые вы хотите читать/обрабатывать/записывать с помощью свойства commit-interval.

 <batch:step id="step1" next="step2"> 
     <batch:tasklet transaction-manager="transactionManager" start-limit="100"> 
      <batch:chunk reader="myReader" processor="myProcessor" writer="MyWriter" commit-interval="800" /> 
      <batch:listeners> 
       <batch:listener ref="myListener" /> 
      </batch:listeners> 
     </batch:tasklet> 
    </batch:step> 

Скажите, что ваш читатель будет вызывать инструкцию SELECT, которая возвращает 10 000 записей. И вы установите интервал фиксации = 500.

MyReader будет вызывать метод read() 500 раз. Скажем, что на самом деле реализация читателя может фактически удалить элементы из набора результатов. Для каждого вызова read() он также вызывается методом process() MyProcessor.

Но он не будет вызывать метод write() MyWriter до тех пор, пока не будет достигнут интервал фиксации.

Если посмотреть на определение интерфейса ItemWriter:

public interface ItemWriter<T> { 

/** 
* Process the supplied data element. Will not be called with any null items 
* in normal operation. 
* 
* @throws Exception if there are errors. The framework will catch the 
* exception and convert or rethrow it as appropriate. 
*/ 
void write(List<? extends T> items) throws Exception; 

} 

Вы видите, что запись получить список элементов. Этот список будет размером вашего фиксированного интервала (или меньше, если конец будет достигнут)

И, кстати, 10 000 записей ничего. Вы можете рассматривать многопоточность, если вам приходится иметь дело с миллионами записей. Но даже тогда достаточно просто поиграть со сладким пятном значения фиксации-интервала.

Надеюсь, это поможет

+0

Большое спасибо за предложение. действительно полезно. – Vimal

+0

мое удовольствие. привет – Cygnusx1

+0

Не могли бы вы посоветовать на http://stackoverflow.com/questions/36391219/bean-property-is-not-readable-or-has-an-invalid-getter-method-does-the-return-t/36391306? ? noredirect = 1 # comment60399566_36391306? –

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