我们有一个具有Sequelize交易的功能。在事务中,它检查数据库表行上的字段,并根据该字段返回或继续更新各种数据库表。
例如
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人无法提交
答案 0 :(得分:0)
读取可以并发运行,因为需要使用同一事务的不同更新才需要导致不可序列化的冲突才能发生错误。因此,要回答一个问题将需要更多信息,但是,如果两个电话都得出相同的最终结果,则不会导致冲突。