我有一个表,用于跟踪批次(在不同表中的其他行)。结构的简化版本如下:
id |类型状态
可以有多种类型的批次(用于不同的操作),并且有多种状态(打开,完成,失败等)。
业务逻辑意味着每种类型只能有0或1个未处理的批次,但是可以有任意数量的未处理的批次。如果在给定批次类型的有效负载进入时没有给定批次类型的未处理批次,则应自动创建一个新批次。
该逻辑的伪代码如下:
SELECT batch WHERE type = (requested batch type goes here) AND status = open
if (!batch exists) {
INSERT INTO batch (requested batch type, open)
SELECT last inserted batch
}
INSERT INTO payload (batch ID, payload data)
我们遇到的问题是一个良好的旧竞争条件,当我们实际上想要一个批次时,当没有未批处理批次时,大量新的有效负载快速涌入会导致创建多个具有单个有效负载的未处理批次。使用分配给该批次的所有传入负载创建。
讨论了许多建议(LOCK TABLES,使用附加表实现锁等),但是对我来说,这些建议似乎都不那么优雅。我真正需要的是检查约束,但MySQL不支持这些约束。交易似乎也不是解决方案,因为我们仍然会得到相同的行为。
UNIQUE复合键也不是一种选择,因为这将只允许每种批次类型的每种状态中的一种。
是否还有其他方法可以让我每个类型只有一个未批处理批处理,但允许多个非未批处理批处理?