我遇到这样的情况:ItemReader 按状态选择表中的项目,而处理器更改状态(从 READY 到 PROCESSED)。 这些已处理的项目(当然)不会被覆盖在下一个块的选择中,导致某些项目根本没有被处理。
第一个块选择并处理 ID 为 1-10 的项目,正确地将状态设置为“已处理”
SELECT t.* FROM the_table t WHERE t.status = READY OFFSET 0 FETCH NEXT 10 ROWS ONLY;
下一个块尝试选择 ids 11-20 by
SELECT t.* FROM the_table t WHERE t.status = READY OFFSET 10 FETCH NEXT 10 ROWS ONLY;
但是由于 1-10 不再被覆盖到 select 中(被第一个块更改),所以 ids 21-30 被选择。项目 11-20 从未被处理
事实也证明,将块大小设置得足够大以覆盖所有潜在的 READY 项目可以提供所需的结果(编写器一次保存所有项目)。但这不是生产的解决方案,因为预计会有大量物品等。
这会导致某些项目根本不会被处理,具体取决于我设置了多少个并行块。
处理这种情况的标准解决方案是什么?
注意: 上面的选择被简化,因为 ItemReader 中使用了更复杂的选择,选择按特定列(ssn)分组的最新可处理项目,而 SUCCESS 状态下没有更新的项目
SELECT bi.*, ri.*
FROM ri_item ri
JOIN item bi ON ri.item_id = bi.id
WHERE (ri.ssn, bi.created_timestamp) IN
(SELECT ri2.ssn, MAX(bi2.created_timestamp)
FROM ri_item ri2
JOIN item bi2 ON ri2.item_id = bi2.id
WHERE ri2.status IN
('READY', 'FAILED_RECOVERABLE')
AND bi2.created_timestamp > COALESCE((SELECT MAX(bi3.created_timestamp)
FROM ri_item ri3
JOIN item bi3 ON ri3.item_id = bi3.id
WHERE ri3.status IN ('SUCCESS')
AND ri3.ssn = ri2.ssn),
TO_TIMESTAMP('1970-01-01', 'YYYY-MM-DD'))
GROUP BY ri2.ssn
)
)
谢谢你
编辑: 我尝试了这个建议,但结果是一样的。明显地。 谁能为我提供如何使用流程指示器模式的简单示例?是这样吗?
非常感谢!!
问题是块步骤中的处理器正在修改状态。然后下一个块的选择在不同的数据集上运行: 选择...偏移 10 限制 10
结果是作业运行时跳过了一半要处理的项目。
解决方案是使用“暂存模式”,它首先选择要处理到单独表中的 id,然后针对此固定暂存列表执行块选择。
可以在随后的某些清理步骤中清除暂存表