在现代 Web 应用程序中,数据库已经成为我们开发人员的常见选择。MongoDB 是最流行的 NoSQL 数据库之一,而 Mongoose 是一个在 Node.js 中高度使用的 MongoDB 的对象模型库,它提供了强大的数据建模和查询功能。事务是在 MongoDB 中处理多个操作的要素之一。在这篇文章中,我们将介绍 Mongoose 的事务使用实例和注意事项,以便您在应用程序中正确而有效地使用它。
什么是事务
在数据库中,事务是一组相互关联的操作,这些操作对于数据库的状态是原子性的,要么全部成功,要么全部回滚。在 MongoDB 中,事务支持多个操作的原子性执行,以确保数据的一致性和完整性。
Mongoose 中的事务
Mongoose 引入了事务 API,该 API 隐藏了 MongoDB 后台的事务实现。Mongoose 中的事务在多数情况下可用,但需满足以下条件:
- 数据库必须是 MongoDB 4.0 及以上版本。
- 集合必须在副本集或分片群集中。
Mongoose 事务示例
在使用 Mongoose 事务时,有几个重要的地方需要注意。首先,必须在支持副本集或分片集群的 MongoDB 实例中启用它。其次,必须使用 Mongoose 嵌套的事务连接而不是连接池。
下面我们通过一个具体的案例来说明如何在 Mongoose 中使用事务。
安装依赖
在开始之前,请确保已安装以下依赖项:
npm i mongoose npm i mongodb
连接数据库
在这个例子中,我们将使用以下格式来连接 MongoDB 数据库:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ----------- - --------------------------------------------- ---------------- - --------------- ----------------------------- - ---------------- ----- ------------------- ---- --- ----- -- - -------------------- -------------- --------------------------- -------- --------- --------------- -- -- - -------------------- ----------- ---
改造模型对象
在使用 Mongoose 的事务前,需要将模型对象进行改造,以支持事务操作。为此,我们需要使用 mongoose.createConnection() 方法来获得一个新的数据库连接,并在该连接对象上使用 startSession() 方法来创建一个会话。关于模型对象改造的具体代码如下:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ------ - ---------------- ----- ----------- - --------------------------------------------- ---------------- - --------------- ----- ---- - -------------------------------------- - ---------------- ----- ------------------- ---- --- ----- -------- ------------------- - ----- ------- - ----- -------------------- --------------------------- --- - ----- ------------ ----- ---------------------------- - ----- ------- - ----- --------------------------- ----- ------ - ------- - --------------------- - - -- ----- ----- ---------- - --- -------- ----- ------- ---- ------ --- ----- --------- - ------------------ ------------
在这个例子中,我们定义了用于创建事务的 withTransaction() 函数,并指定了一个 session 对象,该对象将在事务期间跟踪所有操作。请注意,我们使用了 async/await 关键字来简化嵌套回调。
对于数据库模型,我们只需要将连接引用替换为上述 conn,即可在事务中使用。
实现业务逻辑
接下来,我们将使用上述定义好的数据库模型来执行一些业务逻辑操作,并确保这些操作能够在事务中执行。在这个例子中,我们将在事务中从数据库中删除一个用户。
const userId = "5f792a534a6a181a6c7bb6ce"; withTransaction(async function(session) { await UserModel.deleteOne({ _id: userId }).session(session); });
在上述代码中,我们使用 withTransaction() 方法,将一个函数作为参数传入该方法,并使用 async/await 保证该方法可以异步执行。在该方法内部,我们使用 UserModel.deleteOne() 方法在 session 对象上执行删除操作。
测试
现在我们来测试一下该函数是否在事务中执行。在这里,我们将创建一个事务,删除一个用户,然后尝试查找该用户,以确保该操作被回滚。
-- -------------------- ---- ------- --- - ----- --------------------- ----------------- - ----- --------------------- ---- ------ -------------------- ----- ---- - ----- ------------------- ---- ------ -------------------- -------------------- ------ --- ---------------------- - ----- ----- - -------------------- - -----------
在上述代码中,我们将整个 withTransaction() 方法包含在 try-catch 块中。如果事务成功执行,会输出“事务成功执行”,如果发生错误并回滚了事务,会输出“事务回滚”。
总结
事务是确保数据一致性和完整性的关键要素。在 MongoDB 中,Mongoose 为我们提供了一个简单而强大的事务 API,可帮助我们管理多个相关操作。在这篇文章中,我们介绍了 Mongoose 中的事务,并提供了一个具体的使用案例。希望这篇文章能够对您在实际开发中的事务操作提供帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6487879948841e9894626cd5