首页 > 解决方案 > 使用 mongodb 事务时如何读回结果?

问题描述

到目前为止,我看到的所有 mongodb 事务示例都不允许读取结果。例如(伪代码):

begin_transaction
collection_one.update(...)
collection_two.update(...)
commit_transaction

问题是,如果我想根据更新 collection_one 的结果来更新 collection_two 怎么办?

例如?

begin_transaction
result = collection_one.update(...)
if (result.update_count() > 0)
{
    collection_two.update(...)
}
commit_transaction

我从来没有见过像上面这样的例子?似乎在使用事务时,我无法取回结果。

另一个例子,

begin_transaction
result = collection_children.find({name: 'xxx'})
collection_team.delete({name in result})
commit_transaction

基本上,我想对集合执行查找,并根据查找结果对不同的集合执行第二个操作。

我希望这两个动作一起是原子的。

标签: mongodbtransactions

解决方案


下面是一个示例,说明它如何与 Mongoose 一起按预期工作。没有猫鼬,同样的例子显然是可能的。

var author = new Author({ email: "test22@test.com", other: [{a: 1}});
var book = new Book({ title: 'ABC' })

let doFoo = async () => {
  const session = await mongoose.startSession();
  session.startTransaction();
  try {
    const opts = { session, new: true };

    let _author = await author.save()  // Notice we get back the record
    let _book = await book.save()

    // Notice we are using now the new id of the just saved record
    await Author.findOneAndUpdate({ _id: _author.id }, { $set: { other: { foo: 2 } }},  opts);
    await Book.findOneAndUpdate({ _id: _book.id }, { $set: { title: "ABC" }},  opts);

    await session.commitTransaction();
    session.endSession();
  } catch (error) {
    await session.abortTransaction();
    session.endSession();
    throw error; // Rethrow so calling function sees error
  }
}

doFoo()

因此,在上面的示例中,我们在各自的集合中创建/保存两个不同的记录,然后根据新记录返回并更新它们。


推荐阅读