在使用 MongoDB 数据库进行开发时,我们往往会使用 Mongoose 这个 Node.js 的 ORM 框架来帮助我们完成数据的操作。而在一些情况下,我们需要进行事务控制,例如在数据库中对多个文档进行修改时需要保证这些操作要么全部执行成功,要么全部回滚,以保证数据的一致性。
Mongoose 从版本 5.0.0 开始提供了事务的支持,本文将介绍如何在 Mongoose 中使用事务。
开始一个事务
在 Mongoose 中,我们可以通过创建一个 Transaction
对象来开启一个事务。一个 Transaction
对象包含了当前事务的所有信息,并且可以通过该对象的实例方法来实现事务的管理。
const session = await mongoose.startSession(); session.startTransaction();
以上代码首先通过 mongoose.startSession()
方法来创建一个数据库会话(Session
)对象 session
,然后通过 session.startTransaction()
开启一个事务。
事务中的操作
在事务中,我们可以进行和普通操作一样的数据修改和查询操作,例如通过 Model.updateMany()
方法来修改多个文档:
await Model.updateMany({ name: 'foo' }, { $set: { age: 20 } })
这个操作将会在当前事务中执行,如果该操作执行成功,则这些文档的 age
字段都会被修改为 20。
需要注意的是,由于事务的特殊性,我们需要在进行操作时传入一个额外的参数 session
来绑定这个操作到当前事务对象上。
const session = await mongoose.startSession(); session.startTransaction(); await Model.updateMany({ name: 'foo' }, { $set: { age: 20 } }).session(session);
回滚事务
在事务过程中,我们可以通过调用 Transaction
对象的 rollback()
方法来回滚当前事务中的所有操作。在回滚后,事务中的所有操作都会被撤销。
-- -------------------- ---- ------- ----- ------- - ----- ------------------------ --------------------------- --- - ----- ------------------ ----- ----- -- - ----- - ---- -- - -------------------- ----- ------------------ ----- ----- -- - ----- - ---- -- - -------------------- ----- ---------------------------- - ----- ------- - ----- --------------------------- -
以上代码中,我们通过使用 try-catch
语句来捕获所有的错误,如果有任何一个操作出错,该事务会被回滚,通过调用 session.abortTransaction()
方法来实现事务回滚。
提交事务
在事务成功执行完成后,我们需要调用 Transaction
对象的 commit()
方法来提交该事务。在提交事务成功之前,所有的修改都处于未提交状态,其它连接无法看到这些变更。
-- -------------------- ---- ------- ----- ------- - ----- ------------------------ --------------------------- --- - ----- ------------------ ----- ----- -- - ----- - ---- -- - -------------------- ----- ------------------ ----- ----- -- - ----- - ---- -- - -------------------- ----- ---------------------------- - ----- ------- - ----- --------------------------- -
以上代码中,我们通过调用 session.commitTransaction()
方法来提交事务。
总结
Mongoose 的事务支持为开发者提供了更加灵活和安全的操作数据库的方式,但是在使用事务时需要注意一些细节和异常处理。在实际开发中,我们需要根据具体的业务需求来合理使用事务来保证数据的一致性和完整性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651abc9095b1f8cacd290a52