sequelize.transaction()是否可以将异步函数用作回调?

时间:2019-06-23 21:07:34

标签: javascript node.js async-await sequelize.js

因此,通读Instance上的Sequelize文档以及有关transactions的文档,sequelize.transaction()autoCallback函数用作参数。文档说:

  

使用事务对象调用回调,并且应返回   一个承诺。如果诺言得以解决,则交易将提交;如果   承诺被拒绝,交易回滚

但是我计划在事务内部做很多事情,并且我想避免回调地狱。所以我试图做

try {
    let result = sequelize.transaction({
            isolationLevel: 'SERIALIZABLE'
        }, async t => {
            // code to run here with await
            let var1 = await Model.find({ transaction: t });
            let var2 = await Model.find({ transaction: t });

            if (var1.id === 1)
                return "Whatever result";
            else
                throw new Error("Something wicked");
        }
    )});

    // Whatever result
    console.log(result);
}catch(e){
    // Something wicked
}

这似乎工作得很好。但这是完全没有证件的,我还没有看到任何人使用它。可以,还是我会遇到随机问题?

2 个答案:

答案 0 :(得分:1)

@Bergi@Nicholas Tower在评论中指出:

由于异步函数总是返回promise,而回调函数应该返回promise,所以这是很简单的答案。

是的,可以使用。

答案 1 :(得分:1)

您正在混合样式,如果要使用直接异步/等待,请参见下文。您也没有将事务(代码中的t)传递给查询,因此他们不会使用它-您必须在transaction选项中显式传递它。如果您在提交事务后进行了任何更改,然后在出现任何错误时将其回滚。您还可以通过与Promise.all()同时运行查询来改善代码。

// define outside the try/catch so you can rollback if needed
let transaction;
let result;
try {
    transaction = await sequelize.transaction({ isolationLevel: 'SERIALIZABLE' });

    // run concurrently with Promise.all()
    const [ var1, var2 ] = await Promise.all([
       // don't await here, but you have to pass the transaction
       Model.findByPk({ transaction }),
       Model.findOne({ transaction }), // ditto
    ]);

    if (var1.id === 1) {
       result = "Whatever result";
    } else {
       throw new Error("Something wicked");
    }
    // if you need to commit anything...
    // await transaction.commit();
} catch(err) {
    /* if you need to roll back anything...
    if (transaction) {
       await transaction.rollback();
    }
    */
    console.log(err);
}
return result;