我们有一个具有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)在find上设置锁
let buyingStatus = await models.buyingFood.findOne({ where: { id: 21 }, transaction: t, lock: t.LOCK.UPDATE });
我们想要的是读取未提交的事务,因此如果A更改了之前的bought
状态,则B将无法提交
发布于 2018-11-01 12:45:25
读操作可以并发运行,需要使用相同事务的不同更新需要导致不可序列化冲突才会发生错误。因此,要能够应答一个呼叫将需要更多信息,但如果两个调用的最终结果相同,则不会导致冲突。
https://stackoverflow.com/questions/45865995
复制相似问题