【发布时间】:2018-02-02 14:16:22
【问题描述】:
我们有一个具有 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 无法提交
【问题讨论】:
标签: sql-server node.js transactions sequelize.js isolation-level