Ведение итогов по каждой ветке Spring Batch - PullRequest
0 голосов
/ 10 апреля 2019

Я реализую пакетное приложение Spring, которое выполняет некоторые обновления базы данных. Здесь нет входных / выходных файлов, только прямые обновления базы данных.

Программа выложена так:

  1. Подготовительный тасклет вызывает процедуру DB для получения всех параметров задания и работы, которую необходимо выполнить
  2. работа отправляется партнеру, где работа разбивается на потоки
  3. Запускается тасклет вызова и вызывается в каждом потоке для вызова другой процедуры, которая выполняет фактические обновления в базе данных
  4. После того, как все потоки выполнены, вызывается процедура "end", чтобы закрыть все журналы БД

Моя проблема находится между шагами 3 и 4. После того, как каждый поток завершен, он собирает выходные параметры процедуры, одним из которых является объем работы, который он фактически обновил. Я хочу быть в состоянии сохранить промежуточный итог всех потоков и сколько работы было сделано всеми. Затем эта информация будет передана на шаг 4, который будет включать эти итоги в таблицы журналов БД.

В настоящее время я добавляю любой вывод из процедуры на шаге 3 в Map<String, String> resultMap и вижу общее количество каждого потока. Моя проблема заключается в том, как сохранить все ВСЕ потоки для передачи на шаг 4.

Я попытался объявить пару переменных в верхней части Tasklet Invocation, которые будут использоваться для поддержания промежуточного итога. Проблема в том, что их значения сбрасываются после каждого потока, хотя я использую += при назначении значений из карты

public class SpringBatchInvocationTasklet  implements Tasklet, StepExecutionListener {

   int totalWork = 0;
   int totalWorkProcessed = 0;


    @Override
   public RepeatStatus execute(StepContribution arg0, ChunkContext chunkContext) throws Exception {
      Map<String, String> resultMap = SpringBatchDAO.process(workList, dbLogId, commitVal, userName, threadNo);

      totalWork += Integer.parseInt(resultMap.get(SpringBatchConstants.TOTAL_WORK));
      totalWorkProcessed += Integer.parseInt(resultMap.get(SpringBatchConstants.TOTAL_WORK_PROCESSED));

    }
}

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

Спасибо за любую помощь в этом!

1 Ответ

0 голосов
/ 11 апреля 2019

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

Проблема в том, что их значения сбрасываются после каждого потока, хотя я использую + = при назначении значений из карты

Оператор += не является потокобезопасным, поскольку это не атомарная операция. Вам нужно использовать синхронизацию / блокировки вокруг вашего кода или использовать поточно-ориентированную реализацию Map (например, ConcurrentHashMap) и AtomicInteger (см. incrementAndGet метод) вместо int in для totalWork и totalWorkProcessed переменные.

Может помочь следующий вопрос / ответы: Является ли оператор + = поточно-ориентированным в Java?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...