NestJs 中服务之间的 Mongo 事务

问题描述 投票:0回答:1

我有 2 个服务,每个服务都有自己的事务块,如下所示:

function tranA() {
    const session = await this.connection.startSession();
    try {
        session.startTransaction();

        // Query with the session

        await session.commitTransaction();
    } catch {
        await session.abortTransaction();
    } finally {
        await session.endSession();
    }
}

在一个控制器中,我必须调用这两个服务,并确保它们使用 相同的交易,即相同的

session
。我应该如何处理这个问题?

到目前为止我唯一的想法是将查询移动到单独的函数中,然后传递

session
向下,像这样:

function tranA() {
    const session = await this.connection.startSession();
    try {
        session.startTransaction();

        this.A(session)

        await session.commitTransaction();
    } ...
}

function A(session) {
    // Query with the session
}

然后在控制器中,我创建自己的

session
,然后调用服务。

这种方法最大的问题是方法名称的重复。现在 许多方法有 2 个版本,一种带有外部会话,一种带有自己的会话 会议。

mongodb mongoose transactions nestjs
1个回答
0
投票

您可以将会话设置为可选参数,并有条件地在服务中创建它吗?

我对Nest不太熟悉,似乎它有一个自定义装饰器的选项,但是在vanila节点中,事务装饰器可以这样实现:

async function inTransaction(f, session=null) {
    let result;
    if (!session) {
        const newSession = await this.connection.startSession();
        try {
            newSession.startTransaction();
            result = await f(newSession);
            await newSession.commitTransaction();
        } catch (error) {
            console.log("An error occurred during the transaction:" + error);
            await newSession.abortTransaction();
        } finally {
            await newSession.endSession();      
        }
    } else {
        result = await f(session);
    }
return result;


async function A(arg1, arg2, sessionFromUpstream=null) {
    return inTransaction( session => {
        // body of the function A, for the sake of demo:
        return arg1 + arg2;
    }, sessionFromUpstream);
}

这样,

inTransaction
装饰器将创建一个会话,启动事务,执行函数体,完成事务并关闭会话。如果会话是从上游传递的,例如控制器,事务管理应该在那里处理,并且函数
A
将只使用现有的会话。

© www.soinside.com 2019 - 2024. All rights reserved.