MongoDB 的事务处理方式详解

在前端开发领域,很多应用都需要使用数据库来存储数据。MongoDB 是一种常用的 NoSQL 数据库,它的快速性能和灵活性受到广泛认可。但是,MongoDB 在事务处理方面的处理一直以来备受争议。该文章将详细介绍 MongoDB 的事务处理方式,深入探讨了这种处理的优缺点,并提供一些实用的指导意义和示例代码。

MongoDB 的事务处理

如果您之前不知道,MongoDB 的文档是一个完整的 JSON 对象。因此,作为文档式数据库,之前一直被认为是无法支持事务处理。然而,自从 MongoDB 4.0 推出以来,该数据库现已支持多文档事务处理。这是 MongoDB 开始成为支持关系型数据库的首选解决方案的一个重要里程碑。

MongoDB 的事务处理使用了两阶段提交协议(2PC),这是一种常用的处理分布式事务的协议。在 MongoDB 中,事务的所有操作都必须在同一个副本集合(Replica Set)或者分片集群(Sharded Cluster)中进行。因此,事务处理是分布式的,需要有效的协议来保证原子性、一致性、隔离性、持久性。

在 MongoDB 的事务处理中,有两种类型:基于副本集合的事务处理和基于分片集群的事务处理。这两种方式都涉及到多个文档的读写操作。事务中的操作可以分为读操作和写操作。读操作不需要提交事务,但写操作需要提交事务。

四种事务的执行顺序和结果

MongoDB 中的事务处理是基于四种不同的执行顺序和结果。它们是:

  • 单个操作:单个操作不需要事务而执行。我们不需要考虑提交或回滚这些操作。
  • 多个独立操作:每个操作是独立的,即使其中一个操作失败也不影响其他操作。只有在事务成功提交后,所有操作的结果才会持久化并对客户端可见。
  • 隐式事务:这是一个单个的写操作,它会触发事务,并将操作结果提交到数据库。
  • 显式事务:显式事务是完整的事务,包括开始、提交或回滚三个步骤。这种事务必须包含有一个或多个读写操作,并且需要显式提交才能生效。

在这里,我们主要关注显式事务和其中使用的操作。

MongoDB 的事务处理的优缺点

使用事务处理在任何应用程序中都是有优缺点的。MongoDB 的事务处理也不例外。在这里我们来看看 MongoDB 的事务处理的优缺点:

优点

  • 支持多文档事务:MongoDB 的事务处理支持并发读写多个文档,这意味着多个操作可以在同一个事务内提交或回滚。
  • 原子性:MongoDB 的事务处理为操作序列提供了原子性保证,即使在故障情况下也不会影响数据的完整性。
  • 一致性:操作会遵循事务原则,即事务不完全执行时,MongoDB 会自动回滚到标志位置,使得文档集合保持一致性。
  • 隔离性:MongoDB 的事务处理提供了隔离级别。事务是在隔离级别 SERIALIZABLE 和 READ COMMITTED 下运行的。 READ COMMITTED 提供了非常高的隔离级别,但实现更简单。 SERIALIZABLE 提供了最高级别的隔离,但更加复杂和影响性能。

缺点

  • 性能影响:MongoDB 的事务处理会影响系统性能,因为这需要提供更多的服务器资源来保证事务的性能和可扩展性。
  • 不支持跨文档、跨集合的事务处理:在 MongoDB 的事务处理中只能处理同一副本集或分片集群中的数据。如果需要处理跨文档或跨集合的数据,需要重新设计数据的结构。

MongoDB 的事务处理示例

下面是一个使用 MongoDB 的显式事务处理的示例代码。我们将使用一个简单的账户系统,其中包含用户账户和交易信息的集合。

在这个示例中,我们将使用两个简单的文件:一个用于测试应用程序代码的文件(test.ts),另一个包含商业代码的文件(app.ts)。以下是有关于如何使用 MongoDB 的显式事务处理的示例代码:

app.ts

------ - ----------- - ---- ----------

----- -------- -------------------- ------- --- ------- ------- ------- -
    ----- --- - ----------------------------
    ----- ------ - --- -----------------
    --- -
        ----- -----------------
        ----- -------- - ----------------------
        ----- ------- - ----------------------
        ---------------------------

        ----- --------------- - -----------------------------
        ----- -------- - ----- ------------------------- ---- ---- -- - ------- ---

        -- ----------- -
            ----- ---------------------------
            ----- --- ----------- ---- --- --------- --- --------
        -

        ----- ------ - ----- ------------------------- ---- -- -- - ------- ---

        -- --------- -
            ----- ---------------------------
            ----- --- ----------- ---- --- ------- --- --------
        -

        -- ---------------- - ------ - -- -
            ----- ---------------------------
            ----- --- ------------------- ---------
        -

        ----- --------------------------
            - ---- ---- --
            - ----- - ------- ------- - --
            - ------- --
        --
        ----- --------------------------
            - ---- -- --
            - ----- - ------- ------ - --
            - ------- --
        --

        ----- ----------------------------
        ----------------------- --------- ------ ---- --------- -- ----------
    - ----- --- -
        -----------------
    - ------- -
        ----- ---------------
    -
-

-- -------- -- ------- ---- ---- -- --- -- ---- -- ---
----- --------------------- ------ ----

此代码使用 MongoDB 的 MongoClient API 进行连接到数据库,默认端口(27017)。在此之后,该代码初始化了一个事务会话(session),并开始事务处理。在后续的代码中,会第一次查询到 users 集合中的相应数据,并确保资金充足,而且必须至少有两个查询才能提交或回滚事务。

test.ts

------ - ----------- - ---- ----------
------ - -- --- ---- --------

----- -------- ------ -
    ----- --- - ----------------------------
    ----- ------ - --- -----------------

    --- -
        ----- -----------------
        ----- --------------- - ------------------------------------------

        -- ------ ---- ---- ----
        ----- ----------------------------
            - ---- ------ ------- --- --
            - ---- ------ ------- -- --
        ---

        ----- ------------------------- ------ ----

        -- ----- -------
        ----- -------- - ----- ------------------------- ---- ----- ---
        ----- ------ - ----- ------------------------- ---- ----- ---

        ----------------- ----- ------------------------------
        --------------- ----- ----------------------------
    - ----- --- -
        -----------------
    - ------- -
        ----- ---------------
    -
-

----- -------

此代码在 test() 函数中使用 MongoClient API 连接到 MongoDB,并在 'users' 集合中插入示例数据。在此之后,它调用了从 app.ts 导入的 transferCredit() 函数。请注意,该函数没有返回值,因为它通过打印输出到控制台来展示其执行的结果。测试结束后,请将编写的代码根据测试情况进行修改。

结论

在 MongoDB 4.0 及更高版本中,显式事务处理为支持多文档事务提供了一个更可靠的方式。尽管提供事务处理是一个正确且令人惊喜的决定,但是事务处理仅适用于同一龙门阵集合或分片集群中的数据。因此,当需要处理跨多个集合或数据库的数据时,需要重新设计数据模型。

总的来说,如何有效使用 MongoDB 的事务处理取决于你的应用程序的需求。在大多数情况下,建议仅使用单个文档操作,除非必须在多个文档之间添加事务处理。因此需要权衡性能和数据一致性的影响,以确定是否使用事务。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/670f49fc5f551281026390da


猜你喜欢

  • 解决 Socket.io 连接过程中的跨域问题

    在前端开发中,Socket.io 是一款非常常用的实时通信工具,但是在使用时也会面临一些问题,其中跨域问题是比较常见的。本文将详细介绍在使用 Socket.io 连接时的跨域问题以及解决方法。

    4 天前
  • Angular2 SPA 应用周边技术栈比较

    在前端开发中,单页面应用 (SPA) 已成为一种常见的应用程序架构,Angular2 作为一种流行的前端框架,已经成为了一个SPA开发的重要工具。但是,Angular2 描述的程序架构仅仅是应用的骨架...

    4 天前
  • SASS 中选择器嵌套过深的问题与解决方法

    在前端开发中,CSS 是一项非常重要的技能。而作为 CSS 扩展语言的 SASS,可以帮助前端开发者更好地管理和组织样式。然而,在使用 SASS 的过程中,经常会遇到选择器嵌套过深的问题,这不仅影响代...

    4 天前
  • 在 React 组件中优雅地使用 Redux

    什么是 Redux? Redux 是一个流行的 JavaScript 应用程序状态管理库,它帮助你在你的应用程序中管理数据流。与其他状态管理库相比,Redux 使用了一个单一的全局状态树,这使得数据流...

    4 天前
  • 如何通过 Swagger UI 测试 RESTful API

    Swagger UI 是一款前端工具,用于测试和调试 RESTful API。它可以帮助开发者方便地测试 API,探索 API 文档,同时也可以为 API 文档提供可视化的呈现方式。

    4 天前
  • 通过 import.meta 认识 ES11 中的 JavaScript 模块

    介绍 ES11 中引入了一个新的对象 import.meta,它的作用是在 JavaScript 模块中提供了一些有用的元数据。 在之前的 ES6 标准中,JavaScript 模块可以通过 impo...

    4 天前
  • ECMAScript 2019 中 Symbol.toPrimitive 实现 valueOf 和 toString 的替代者

    ECMAScript 2019 中 Symbol.toPrimitive 实现 valueOf 和 toString 的替代者 在 ECMAScript 2019 中,Symbol.toPrimiti...

    4 天前
  • 前端响应式设计中图片 lazyload 的实现方法

    响应式设计是现代 Web 设计中的重要概念之一。它的主要目的是让网页在不同设备、不同浏览器和不同屏幕宽度下都能够自动适应,提供更好的用户体验。其中一个常常被忽视的方面是图片的加载和优化,尤其是在移动设...

    4 天前
  • 如何起步并完成一个最小的 Hapi.js 服务

    Hapi.js 是一个流行的 Node.js web 应用框架,它提供了丰富的功能,包括路由、请求处理、插件、参数校验等等。在本文中,我们将介绍如何使用 Hapi.js 来搭建一个最小的 web 服务...

    4 天前
  • 微服务框架:GraphQL vs REST vs 微服务

    随着Web应用的发展和需求变化,前端开发人员越来越多地使用微服务框架来构建高性能和可拓展的应用程序。在这篇文章中,我们将深入探讨三种流行的微服务框架:GraphQL、REST和微服务。

    4 天前
  • 如何在 Fastify 框架中使用 Handlebars 视图引擎

    Handlebars 是一个 JavaScript 模板引擎,可以帮助我们动态生成 HTML 页面,它的语法简单易懂,支持条件判断、循环等常用操作,受到了广泛应用。

    4 天前
  • 在 Deno 中如何使用 Jest 进行单元测试

    介绍 Deno 是一个 JavaScript 和 TypeScript 运行时环境,由 Node.js 的创建者 Ryan Dahl 打造。和 Node.js 不同,它内置 TypeScript 支持...

    4 天前
  • PWA 推送功能如何实现?

    PWA(Progressive Web App)是一种新型的 web 应用程序,具有类似于原生应用的功能和体验。其中一个重要的功能是推送通知功能,它能够让用户在离线状态下也能收到来自应用程序的提示,增...

    4 天前
  • Sequelize 中如何处理虚拟字段的使用

    在开发 Web 应用中,使用 ORM 框架来管理数据库非常方便。Sequelize 是一款流行的 Node.js ORM 框架,它可以支持多种数据库系统,如 MySQL、PostgreSQL、SQLi...

    4 天前
  • Next.js 中如何进行数据预取?

    Next.js 是一款用于构建 React 应用程序的框架,它提供了许多有用的功能,包括自动代码分割、服务端渲染、预取数据等。在本文中,我们将重点介绍在 Next.js 中如何进行数据预取。

    4 天前
  • 在 ES11 中严格模式和宽松模式到底有何区别!

    当我们学习 JavaScript 时,可能听过严格模式和宽松模式,但具体它们有什么区别呢?在 ES11 中,这一问题得到了更加明确的回答,本文将为大家详细介绍严格模式和宽松模式的区别,并给出示例代码。

    4 天前
  • TypeScript 中如何使用对象展开语法

    TypeScript 是 JavaScript 的一个类型化超集,它增加了许多新的语言特性,提供了更好的开发体验。对象展开语法是 TypeScript 的一种特性,允许我们使用一种简洁的语法来快速创建...

    4 天前
  • Fastify 中间件开发实践

    Fastify 是一种高度优化的 web 服务器框架,其特点是非常快速且可扩展。此外,它还支持各种中间件。Fastify 中间件可以扩展应用程序的功能,例如安全性、压缩、日志记录、验证等等。

    4 天前
  • 获取海量正版素材,Headless CMS 的绝佳利器

    在前端开发中,常常需要使用一些图片、音视频等素材来丰富页面的展示效果,但是找到合适的素材并非易事。同时,很多网站和应用程序需要与内容管理系统(CMS)结合使用,以便快速有效地管理和更新网站内容。

    4 天前
  • Jest 测试中的异常处理最佳实践

    Jest 是一个流行的前端测试框架,可以对 JavaScript 应用程序进行快速的单元测试、集成测试和端到端测试。在开发过程中,最常见的 - 也是最重要的 - 是确保您的代码可以正常运行。

    4 天前

相关推荐

    暂无文章