前言
在开发中,经常需要进行多个操作,例如关联的数据更新、统计信息的计算等。当这些操作需要保证原子性时,需要使用事务处理,即一组多个操作要么全部成功,要么全部失败。Mongoose 是 Node.js 中操作 MongoDB 数据库的框架,提供了方便的事务处理方式,下面将介绍 Mongoose 中的事务处理。
Mongoose 中的事务处理
Mongoose 从 5.0 版本开始支持事务处理。具体实现使用 MongoDB 4.0 引入的事务处理。Mongoose 中使用事务处理的一个关键概念是会话(Session)。会话是在 Mongoose 和 MongoDB 之间的桥梁,它允许我们跨多个操作共享事务上下文。
Mongoose 中通过在 Schema 中使用 transaction: true
来开启事务处理。在事务中,我们尝试执行一组操作,并在这些操作之间维护原子性。如果这些操作中的任何一个失败,所有操作都会回滚,也就是之前执行过的所有操作都会撤销。最终结果是,所有事务内的操作要么都成功,要么都失败。
关于事务的概念可以看阮一峰老师的博客:数据库事务教程。
下面看一下 Mongoose 中的事务处理详细说明。
1. 开始事务
使用 Mongoose 进行事务处理,首先需要开启会话(Session)。我们可以通过调用 mongoose.startSession()
创建一个会话。如下所示:
const session = await mongoose.startSession();
创建完成后,我们可以在此会话上执行各种操作,这些操作可以共享事务上下文。接下来,我们调用 session.startTransaction()
开始事务。如下所示:
await session.startTransaction();
这样,我们就成功开启了一个 Mongoose 事务。
2. 向事务中添加操作
现在,我们已经成功开启了一个 Mongoose 事务,下面可以向其中添加一些操作了。在事务中执行任何操作都如同普通操作一样,只是在执行时需要传入会话对象。以更新一个用户数据为例,如下所示:
-- -------------------- ---- ------- --- - ----- --------------------------- - ---- ------ -- - ----- - ----- ------- - -- - ------- - --------- - ----- ------- - ------------------------ ------- ------ ------------------- -
为了在事务中执行操作,我们需要将会话对象作为 options 参数传递给操作(即上例中的 session
)。
这些操作的类型可以是任何类型,包括插入、更新、删除等。
3. 发起提交或回滚
在事务完成时,我们需要提交或回滚事务。提交意味着所有操作都成功完成,而回滚意味着所有操作都失败了。Mongoose 中,分别使用 session.commitTransaction()
和 session.abortTransaction()
发起提交或回滚。
至此,我们已经完成了 Mongoose 中的事务处理,具体实现代码可以参考下面的示例。
示例代码
下面是一个简单的示例代码,展示了如何使用 Mongoose 进行事务处理。
-- -------------------- ---- ------- ----- - ----------- ------ - - -------------------- ------ -- -- - -- -- ------- -- ----- ----------------------------------------------------- -- ------ ----- ---------- - --- -------- ----- ------- ---- ------ -- - ------------ ---- -- ---- --- ----- ---- - ------------------------ ------------ -- ---- ----- ------- - ----- -------------------------- ----- --------------------------- --- - -- ------ ----- ------- - --- ------ ----- -------- ---- -- --- ----- -------------- ------- --- -- ------ ----- --------------- - ---- ----------- -- - ----- - ---- -- - -- - ------- - -- -- ---- ----- ---------------------------- ------------------------ ------------- - ----- ------- - -- ---- ----- --------------------------- ------------------------ ------- ------ ------------------- - ------- - -- ---- --------------------- - -- -- ------- -- ----- ------------------- -----
注意,由于 MongoDB 不支持跨两个或更多分片的事务,所以必须在同一分片上执行事务。如果要在多个分片之间执行事务,则必须将分片集合到副本集或分片集群中。
总结
Mongoose 从 5.0 版本开始支持事务处理。事务中的操作可以保证原子性,也可以统一提交或回滚操作。使用起来非常方便,它的应用范围广泛。在多个操作之间确保原子性时,事务处理非常有用。希望本篇文章对您有所启示。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6596839beb4cecbf2da53704