这两种方法有区别吗?
const something = Model.findById(id).
something.save({ session })
const something = Model.findById(id).session(({ session })
something.save()
测试时,功能是相同的。在mongoose事务中使用会话的正确方法是什么?
首先在交易中你需要async/await
,
const something = await Model.findById(id).
await something.save({ session })
但是事务允许你在isolation
和potentially
中执行多个操作,如果其中一个操作失败,撤销所有操作,事务的主要目标是让你在MongoDB中隔离update multiple documents
。
,但是在您的示例中,您更新了一个集合,并且不需要事务。让我们继续……请看下面的例子,在这个例子中结果是不同的,这个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' });//without session
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()中使用该会话,如下例所示找不到result
,因为save()
是未提交事务的一部分,但firstReuslt
不是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' }); //Is Null
await session.commitTransaction();
session.endSession();
firstReuslt = await Model.findOne({ name: 'firstTest' });//Is Not Null
如果你想更新两个集合,应该使用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();