java - 如何在已经分区的步骤中禁用块?
问题描述
假设我有 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 之外,我没有看到任何解决方案,因此每个对象都在一个方法调用中处理。但不知何故感觉很脏。
解决方案
我想到了。我可以使用 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);
}
推荐阅读
- java - 如何在 java 中捕获 400 错误请求
- java - Appium java - 页面对象模型未被识别
- python - Discord.py - 如何让人们等待一段时间才能再次使用命令?
- ajax - 为什么最简单的用户 AJAX 注册在 WordPress 中不起作用?
- react-native - 在 React Native 中从 axios 访问 Redux 存储
- json - JSON 数据架构 allOf $ref 外部 json 架构文件不起作用
- angular - 关闭应用程序时,Ionic 5 是否为服务和主页调用 ngOnDestroy
- delphi - 如何在同一个 IIS 上运行多个 Delphi RAD Server 应用程序?
- javascript - 有没有办法比较 HTML 中两个选定表格的行?
- javascript - 尝试使用 React Hook 渲染页面时出错