说我有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之外,我没有其他解决方案,因此每个对象都在一个方法调用中处理。但这感觉有点脏。
答案 0 :(得分:0)
我知道了。代替读取器/处理器/写入器,我可以改用Tasklet。 使用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);
}