简体   繁体   English

Nodejs mongodb 在事务中查找并更新多个文档

[英]Nodejs mongodb find and update multiple documents in transaction

I have a mongo 4.2 replica set.我有一个 mongo 4.2 副本集。 I have N processes running concurrently and trying to read a collection.我有 N 个进程同时运行并试图读取一个集合。 This collection is like a queue.这个集合就像一个队列。 I'd like to read 100 elements and update them in a transaction so other processes won't try to read those.我想读取 100 个元素并在事务中更新它们,以便其他进程不会尝试读取这些元素。

My code goes:我的代码是:

const collection = client.db("test").collection(TEST_COLLECTION);

const session = client.startSession();

try {

    let data = null;

    await session.withTransaction(async () => {
        console.log("starting transaction")

        data = await collection.find({ runId: null }, { _id: 1, limit: 100 }).toArray();

        const idList = data.map(item => item._id.toHexString());

        await collection.updateMany(
            { runId: { $in: idList } },
            { $set: { runId: runId } },
            { session });

        console.log("Successful transaction")
    });

    data.map(item => {
        // process element one by one and update them (no need for transaction here)
    })

} catch (e) {
    console.error("The transaction was aborted due to an unexpected error: " + e);
} finally {
    await session.endSession();
    console.log("Closing transaction")
}

this is the code I've got right now.这是我现在得到的代码。 The thing is that find() won't accept options so I can't pass the session.问题是 find() 不会接受选项,所以我无法通过会话。 This means it won't be part of the transaction.这意味着它不会成为交易的一部分。

the mongodb documentations states that: When using the drivers, each operation in the transaction must be associated with the session (ie pass in the session to each operation). mongodb 文档指出:使用驱动程序时,事务中的每个操作都必须与会话相关联(即,将会话传递给每个操作)。

So I'm assuming that this is actually not transactional only the update part which not solves my problem.所以我假设这实际上不是事务性的,只是更新部分不能解决我的问题。 Is there any way to include both in my transaction?有什么办法可以将两者都包含在我的交易中吗? Any ideas on this?对此有何想法? Other/better options?其他/更好的选择?

Thanks谢谢

EDIT: So I was staring at my question for 15 minutes when it hit me.编辑:所以当它击中我时,我盯着我的问题 15 分钟。 If I update first using the transaction.如果我首先使用交易进行更新。 Then querying with the runId even outside of the transaction I can achieve my goal.然后即使在事务之外使用 runId 进行查询,我也可以实现我的目标。 Am I right?我对吗? Is it so easy?有那么容易吗?

EDIT2: Edit1 was stupid now I can't limit to 100 items. EDIT2: Edit1 很愚蠢,现在我不能限制为 100 个项目。 Back to the start.回到起点。

EDIT3: I'am using native mongodb nodejs driver. EDIT3:我正在使用本机 mongodb nodejs 驱动程序。

To use a find in a transaction, pass the session using the session method:要在事务中使用find ,请使用session方法传递session

doc = await Customer.findOne({ name: 'Test' }).session(session);

See Transactions in Mongoose查看Mongoose 中的事务

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM