gpt4 book ai didi

node.js - Sequelize : findOne auto commits during transaction (using clsHooked)

转载 作者:行者123 更新时间:2023-12-03 22:27:01 30 4
gpt4 key购买 nike

我有类似于下面的代码:

const _addEvents = async(eventList, day, transaction) => {
await eventList.forEach(event => {
return model.events.findOne({where:event, transaction: transaction}).then(event => {
if(!event) {
transaction.rollback();
throw new Error("event not found");
}

return event;
})
.then(event => {
day.addEvents(event, {through: {status: 'ENABLED'}});
day.save();
})
})
}
}

export const create = async(attributes) => {
return await sequelize.transaction(async(t) => {
return model.days.create(attributes, {transaction: t})).then(async(day) => {
await _addEvents(attributes.eventList, day, t);
return day;
})
})
}

我看到的是交易开始,交易中的天数增加了一行。在第一次迭代中,当在 findOne 方法中调用 _addEvents 时,事务被提交。

我使用了 Sequelize.useCLS("foo");,所以我希望所有事务都在同一个命名空间中,但是我传递事务只是为了确定。

谁能告诉我为什么在执行 findOne 之后提交事务,并告诉我如何避免这种情况发生。

我正在使用 (babel-core 6.26.3) 和 node.js v9.2.0 & postgres 10.5

最佳答案

感谢 @Jan Aagaard Meier & Co 揭示了这个问题。

我的问题是 await eventList.forEach 没有做我希望它会做的事情。
Array.prototype.forEach 将返回 undefined 。它将返回与循环内 promise 的状态无关。

因此 COMMIT 发生是因为事务功能在丢失的 Promise(在循环内)完成之前完成。

一个解决方案是使用 bluebird's Promise.map 将那条线变成

await Promise.map(eventList, async(event) => {
await model.events.findOne({where:event, transaction: transaction}).then(event => {
....
}
});

这里 map 将等到所有子 promise 完成,当我们返回一个 promise (并等待它)时,我们确保我们不会在 map 完成之前完成交易。

关于node.js - Sequelize : findOne auto commits during transaction (using clsHooked),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54535907/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com