【问题标题】:Using sequelize transactions with nested then()使用带有嵌套 then() 的 sequelize 事务
【发布时间】:2021-12-04 09:43:33
【问题描述】:

我在此链接上阅读了续集中的所有交易文档:https://sequelize.org/master/manual/transactions.html 并在谷歌搜索多个解决方案,但我没有找到我需要的确切解决方案。

所以我的问题是我正在尝试将嵌套事务与 sequelize 一起使用,我只想在全部成功后才执行所有查询。所以这就是我尝试的:(这是实际代码的最小化版本,以改善您的阅读体验)

try {
    await db.sequelize.transaction(async (t1) => {
        const promises = Promise.all(
            Object.keys(DefaultLicencesConfigurations).map((defaultLicenceConf) => {
                const licenceConfDefault = DefaultLicencesConfigurations[defaultLicenceConf]

                return LicencesConfigurations.create(
                         {Param} // Just for the example to make the code smaller, 
                         {transaction: t1})
               .then((licenceConf) => {
                        return licenceConf
                    })
            })
        )

        promises.then((licenceConf) => {

            UserRoles.findOne({where:{role:UserRolesTypes.ARTIST}}).then(async (role) => {
                    await db.sequelize.transaction({
                        transaction: t1
                    }, async (t2) => { // It seem the code is bloqued here
                        Users.update(
                            {ID_user_role: role.id}, 
                            {
                                where: {id: artist.ID_user},
                                transaction: t2
                            })
                            .then((user) => {
                                // Code didn't come here
                                console.log(user)
                            })
                            .catch((error) => {
                                // If i console.log() here it show the console log so it's catched
                            })
                    })
                })
        })
    })
} catch (error) {
    console.log(error)
}

那么我在这里做错了什么?我正在使用不同的事务,但第二个事务 (t2) 仍然出现错误。如果我完全删除事务(t2),它可以正常工作,但我们失去了事务的实用性,因为即使事务失败,代码也会被执行。

---------- 编辑 --------------------------------- ------------

我为此promise all 部分创建了一个新方法,但问题是当我在与LicencesArtists 的t5 交易中出现错误时,promise 无论如何都会解决,并且无论如何都会创建LicencesConfigurations。有什么解决办法吗?

const createLicencesConfiguration = async (artistID, transaction) => {
    return await db.sequelize.transaction({ transaction }, async (t4) => {
        return await Promise.all(
            Object.keys(DefaultLicencesConfigurations).map(async (defaultLicenceConf) => {
                const licenceConfDefault = DefaultLicencesConfigurations[defaultLicenceConf]

                const licenceConf = await LicencesConfigurations.create(
                    {
                        name: licenceConfDefault.name,
                        default_price_dollars: licenceConfDefault.default_price_dollars,
                        limit_copies_sales: licenceConfDefault.limit_copies_sales,
                    },
                    { transaction: t4 }
                )

                if (!licenceConf) {
                    return null
                } else {
                    return await db.sequelize.transaction({ transaction: t4 }, async (t5) => {
                        return await LicencesArtists.create(
                            {
                                ID_artist: null /*artistID*/ // I do that for generate an error,
                                ID_licence_configuration: licenceConf.id,
                            },
                            { transaction: t5 }
                        )
                    })
                }
            })
        )
    })
}

他在插入部分为 licences_artists 做了回滚,但最后他commit,为什么?

Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): INSERT INTO `licences_artists` (`ID_artist`,`ID_licence_configuration`) VALUES (?,?);Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): ROLLBACK TO SAVEPOINT `54f84ba7-7cde-450a-92e1-d5f9326fcd05-sp-1`;
Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): ROLLBACK TO SAVEPOINT `54f84ba7-7cde-450a-92e1-d5f9326fcd05-sp-2`;
Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): ROLLBACK TO SAVEPOINT `54f84ba7-7cde-450a-92e1-d5f9326fcd05-sp-3`;
Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): ROLLBACK TO SAVEPOINT `54f84ba7-7cde-450a-92e1-d5f9326fcd05-sp-4`;
Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): ROLLBACK TO SAVEPOINT `54f84ba7-7cde-450a-92e1-d5f9326fcd05-sp-5`;
Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): ROLLBACK TO SAVEPOINT `54f84ba7-7cde-450a-92e1-d5f9326fcd05-sp-5`;
Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): ROLLBACK TO SAVEPOINT `54f84ba7-7cde-450a-92e1-d5f9326fcd05-sp-5`;
Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): ROLLBACK TO SAVEPOINT `54f84ba7-7cde-450a-92e1-d5f9326fcd05-sp-5`;
Executing (54f84ba7-7cde-450a-92e1-d5f9326fcd05): COMMIT;

【问题讨论】:

  • awaits 和 thens 的组合看起来真的很乱。你可以只使用await 并让你的代码更直接和线性吗?
  • 我编辑帖子以使代码更具可读性谢谢!

标签: node.js express transactions sequelize.js


【解决方案1】:

你需要等待 t2 在 t1 完成。像这样使用await

    try {
        await db.sequelize.transaction(async (t1) => {
            const licences = await Promise.all(
                Object.keys(DefaultLicencesConfigurations).map((defaultLicenceConf) => {
                    const licenceConfDefault = DefaultLicencesConfigurations[defaultLicenceConf]

                    return LicencesConfigurations.create({
                        }, {
                            transaction: t1
                        })
                        .then((licenceConf) => {
                            return licenceConf
                        })
                }
            ));

            const role = await UserRoles.findOne({
                    where: {
                        role: UserRolesTypes.ARTIST
                    }
            })
            await db.sequelize.transaction({ transaction: t1 }, async (t2) => {
                const user = await Users.update({
                        ID_user_role: role.id
                    }, {
                        where: {
                            id: artist.ID_user
                        },
                        transaction: t2
                    })
            })
        });
    } catch (error) {
        console.log(error)
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多