Как отключить чанки в уже разделенном шаге? - PullRequest
0 голосов
/ 27 сентября 2019

Скажем, у меня есть 100 городов, и у каждого города есть интересные объекты.

Количество объектов варьируется и может варьироваться от 0 до N.

Объекты могут быть удалены из списка чтения.Это означает, что они больше не активны, и я должен их отключить.Поэтому сначала я отключаю ВСЕ объекты в городе - от автора, а затем снова активирую те, которые все еще находятся в списке, так как я все равно должен их обновить.

Я использую Spring Batch для чтения объектовна каждый город и записать их в базу данных.Я уже разбил этот шаг на части, поэтому данные по каждому городу читаются и записываются на его собственном шаге подчиненного.

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

Spring Batch - это удивительный инструмент, который подходит практически ко всем моим потребностям, но теперь мне интересноЕсли это правильный инструмент для этой конкретной работы.

Скажем, у нас есть 2 города: id1 city1 id2 city2

И у каждого города есть объекты.Объекты могут быть активными или неактивными.Каждый из них привязан к городу (извините, Stackoverflow, похоже, не поддерживает какие-либо таблицы).

object1 city1 active
object2 city1 active
object3 city1 inactive
object1 city2 active
object2 city2 inactive

И я могу получить только текущие активные объекты из читателя:

object1 city1 active
object3 city1 active
object1 city2 active

Значение - все другие объекты в моей БД должны быть отключены перед тем, как я начну обновлять активные.

Итак, я делаю это в писателе:

CityObjectWriter(CityObjectRepository cityObjectRepository, cityId){
    this.cityObjectRepository = cityObjectRepository;
    this.cityId = cityId;
}

@Override 
public void write(List<? extends CityObjectData> cityObjectData) throws Exception{
    //In this case i should do nothing
    if (cityObjectData.isEmpty) return;
    cityObjectRepository.disableObjectsByCityId(cityId);
    List<CityObject> cityObjects = cityObjectRepository.findAllByCity(cityId);
    // Finds a matching existing cityObject and updates it with new data, if it's found
    updateCityObjects(cityObjects, cityObjectData);
}

Вы видите проблемуздесь?

Поскольку Spring Batch разбивает данные на куски - все N записей будут записываться в своем собственном методе write ().И каждый вызов этого метода будет деактивировать все остальное.Даже записи, которые ранее были активированы.Я не хочу этого, и я не вижу никакого решения, кроме установки размера чанка 9999999, поэтому каждый объект обрабатывается одним вызовом метода.Но это как-то грязно.

1 Ответ

0 голосов
/ 30 сентября 2019

Я понял это.Вместо читателя / процессора / писателя я могу использовать Tasklet.Шаг, использующий тасклет, можно разделить на этапы подчиненного устройства, а также обычный шаг с помощью программы чтения / записи / процессора.Он будет читать, обрабатывать и записывать каждый объект города в одной транзакции:

CityObjectImportTasklet(CityObjectRepository cityObjectRepository, cityId){
    this.cityObjectRepository = cityObjectRepository;
    this.cityId = cityId;
}

@Override 
public RepeatStatus execute(StepContribution contribution, ChunkContext context) throws Exception {
    List<CityObjectData> cityObjectData = getCityObjectDataSomehow(cityId);

    //In this case i do nothing
    if (cityObjectData.isEmpty) return;

    //disable all existent objects, to activate them later in case they're present
    cityObjectRepository.disableObjectsByCityId(cityId);

    List<CityObject> cityObjects = cityObjectRepository.findAllByCity(cityId);
    // Finds a matching existing cityObject and updates it with new data, if it's found
    updateCityObjects(cityObjects, cityObjectData);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...