具有延迟约束的Postgres Sequelize交易不起作用

时间:2019-12-18 10:59:46

标签: node.js postgresql transactions sequelize.js deferred

目的: 我正在尝试在事务内的相关表中进行更改。

操作: 我已经更改了表中的约束,以将它们设置为DEFERRABLE INITIALLY DEFERRED以便能够在事务内的引用表中提交。 Just like in this article.

所以在我的表格中有两个FK约束:

Foreign-key constraints:
    "updaters_features_updater_id_fkey" FOREIGN KEY (updater_id) REFERENCES updaters(id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
    "updaters_features_feature_id_fkey" FOREIGN KEY (feature_id) REFERENCES features(id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED

我正在使用

进行交易
sequelize.transaction({
    deferrable:  this.db.sequelize.Deferrable.SET_DEFERRED,
}, t => {
    //insert into updates table
    //insert into updates_features table 
})

它会生成下一个SQL查询:

START TRANSACTION;
SET CONSTRAINTS ALL DEFERRED
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
INSERT INTO "public"."updaters" ("id","description","is_full","created_at","updated_at","android_model_id","version_from_id","version_to_id") VALUES (DEFAULT,'Description',true,'2019-12-18 09:46:21.272 +00:00','2019-12-18 09:46:21.272 +00:00',1,31,32) RETURNING *;
INSERT INTO "public"."updaters_features" ("created_at","updated_at","feature_id","updater_id") VALUES ('2019-12-18 09:46:21.267 +00:00','2019-12-18 09:46:21.267 +00:00',3,280),('2019-12-18 09:46:21.267 +00:00','2019-12-18 09:46:21.267 +00:00',5,280);

并且由于违反外键约束Key (updater_id)=(280) is not present in table "updaters".

而失败

如果我从控制台复制SQL查询并在psql中手动运行它,我找不到问题和最奇怪的地方-一切工作都很好,我可以提交事务。

我一直在寻找this question,但遇到了不同的问题。

UPD(应用交易代码的JS):

await this.withTransation({
    deferrable:  this.db.sequelize.Deferrable.SET_DEFERRED,
}, async(transaction) => {
    update = await this.dbModel.create({
        version_from_id: body.buildFrom,
        version_to_id: body.buildTo,
        android_model_id: body.modelId,
        description: body.description,
        isFull: body.isFull,
    }, {transaction});
    await this.db.UpdatersGroups.bulkCreate(body.groupIds.map((groupId) => ({
        feature_id: groupId,
        updater_id: update.id,
    })));
});

withTransaction是我的抽象,我确信它可以正确运行(只需在续集中创建非托管事务)

1 个答案:

答案 0 :(得分:1)

第二个查询不在事务上下文中执行,因此添加transaction应该会有所帮助:

...
await this.db.UpdatersGroups.bulkCreate(body.groupIds.map((groupId) => ({
    feature_id: groupId,
    updater_id: update.id,
}), { transaction })); // transaction here is applied.