我们有一个函数,它有一个后继事务。在事务中,它检查数据库表行上的字段,并基于该字段返回或继续更新各种数据库表。
例如

let buyingStatus = await models.buyingFood.findOne({ where: { id: 21 }, transaction: t});
if (buyingStatus.status == 'bought') return 'already bought'

如果继续,它将更新多个位置,只有在状态不是bought时才会更新,最后,将状态更改为bought
问题是当函数同时被调用两次时。瓶颈是select语句之后发生的更新。因此,两个人可以通过“未购买”的购买状态,然后更新bought状态以及所有其他更新。
由于不是sql专家,我们研究发现锁定表或更改隔离级别可以解决这个问题。然而,我们同时实现了这两个目标,却没有帮助。见下文
1)改变隔离等级
let t = await models.sequelize.transaction(isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE);

2)锁定查找
let buyingStatus = await models.buyingFood.findOne({ where: { id: 21 }, transaction: t, lock: t.LOCK.UPDATE });

我们想要的是从未提交的事务中读取,因此如果人员A在其之前更改了bought状态,那么人员B将无法提交

最佳答案

读取可以并发运行,不同的更新需要使用相同的事务,这需要导致不可序列化的冲突才能发生错误。因此,要回答一个问题需要更多的信息,但如果两个调用都导致相同的最终结果,则不会导致冲突。

10-05 20:00