首先在事务处理中,你需要使用 async/await
。
const something = await Model.findById(id).
await something.save({ session })
但是使用事务可以在隔离
的情况下执行多个操作,如果其中一个操作失败,可以可能地
撤销所有操作,事务的主要目标是在MongoDB中让你以隔离
的方式更新多个文档
。
但在您的示例中,您只更新了一个集合,不需要使用事务。我们来看下面的例子,这个create()
是因为session
而成为事务的一部分,而事务是在隔离环境中执行的,所以除非你将session
传递给findOne()
,否则在提交事务之前你不会看到结果。因此,findOne
的结果是null
。
const session = await db.startSession();
session.startTransaction();
await Model.create([{ name: 'Test' }], { session: session });
let result = await Model.findOne({ name: 'Test' });
session.endSession();
在以下示例中,这个
findOne()
将返回结果,因为传递了
session
,这意味着这个
findOne()
将作为事务的一部分运行。
const session = await db.startSession();
session.startTransaction();
await Model.create([{ name: 'Test' }], { session: session });
let result = await Model.findOne({ name: 'Test' }).session(session);
session.endSession();
如果您使用会话从findOne()或find()获取一个Mongoose文档,则该文档将保留对会话的引用,并在save()中使用该会话,在以下示例中,由于save()是未提交事务的一部分,因此不会找到result,但firstResult不是Null。
const session = await db.startSession();
session.startTransaction();
await Model.create({ name: 'Test' });
const something = await Model.findOne({ name: 'Test' }).session(session);
something.name = 'firstTest';
await something.save();
let result = await Model.findOne({ name: 'firstTest' });
await session.commitTransaction();
session.endSession();
firstReuslt = await Model.findOne({ name: 'firstTest' });
如果您想要更新两个集合,可以使用以下代码:
save({session:sess})
,但如果您只想更新一个集合,则不需要使用该代码,因为:
如果使用会话从findOne()或find()获取Mongoose文档,则文档将保留对该会话的引用,并使用该会话进行save():
const sess = await mongoose.startSession();
sess.startTransaction();
await first.save({ session: sess });
await second.save({ session: sess });
await sess.commitTransaction();