具有延迟约束的 Postgres Sequelize 事务不起作用
Postgres Sequelize transaction with deferred constraint doesn't work
用途:
我正在尝试对交易中的相关 table 进行更改。
操作:
我已经更改了 table 中的约束以将它们设置为 DEFERRABLE INITIALLY DEFERRED
以便能够在事务内部引用的 table 中提交。 Just like in this article.
所以在我的 table 中有两个 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
是我的抽象,我确信它可以正常工作(只需在 sequelize 中创建非托管事务)
第二个查询未在事务上下文中执行,因此添加 transaction
应该会有所帮助:
...
await this.db.UpdatersGroups.bulkCreate(body.groupIds.map((groupId) => ({
feature_id: groupId,
updater_id: update.id,
}), { transaction })); // transaction here is applied.
用途: 我正在尝试对交易中的相关 table 进行更改。
操作:
我已经更改了 table 中的约束以将它们设置为 DEFERRABLE INITIALLY DEFERRED
以便能够在事务内部引用的 table 中提交。 Just like in this article.
所以在我的 table 中有两个 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
是我的抽象,我确信它可以正常工作(只需在 sequelize 中创建非托管事务)
第二个查询未在事务上下文中执行,因此添加 transaction
应该会有所帮助:
...
await this.db.UpdatersGroups.bulkCreate(body.groupIds.map((groupId) => ({
feature_id: groupId,
updater_id: update.id,
}), { transaction })); // transaction here is applied.