SQL Server 的 Sequelize 事务隔离级别问题

Posted

技术标签:

【中文标题】SQL Server 的 Sequelize 事务隔离级别问题【英文标题】:Sequelize Transaction isolation level issue with SQL server 【发布时间】: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 无法提交

【问题讨论】:

【参考方案1】:

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

【讨论】:

以上是关于SQL Server 的 Sequelize 事务隔离级别问题的主要内容,如果未能解决你的问题,请参考以下文章

sequelize 跟 原生sql相比 会太多的影响性能么

GraphQL/Sequelize:SQL 别名

提交的Sequelize事务的结果为“未定义”

sequelize更新事务锁定行

sql server中的事务是啥意思

sql server 2012 事务日志在哪