MongoDB 事务处理原理和实践

AI 编程助手,豆包旗下的编程助手,提供智能补全、智能预测、智能问答等能力,节省开发时间,释放脑海中的创造力,支持 VSCode,点击体验 AI

前言

MongoDB 是当今最流行的 NoSQL 数据库之一,它的高性能和灵活性为各种应用场景提供了解决方案。然而,在一些需要强一致性的场景下,它的事务处理能力不够强大,这也一度成为其被批评的原因之一。

随着 MongoDB 4.0 和 4.2 的发布,它们都提供了原生的事务支持,让开发者在更为意外的情况下轻松地处理了各种操作。本文将深入探讨 MongoDB 的事务处理原理,并使用具体的示例代码演示 MongoDB 的事务处理实践。

MongoDB 事务基础知识

MongoDB 原生事务处理仅针对副本集和分片集群,由于仅有这两种部署方式才能有效保证事务的一致性。在 MongoDB 中,一个事务由多个操作序列组成,每个操作都可以是插入、更新、删除等。MongoDB 的事务一般在单个文档中执行,因此在事务处理时需要注意数据结构的规范性。

MongoDB 支持的事务类型包括:

  • 读事务:执行读取操作的事务
  • 写事务:执行更新、插入或删除操作的事务
  • 混合事务:同时包含读取和写入操作的事务

MongoDB 的事务处理使用类似于 SQL 事务的 Commit 和 Rollback 两个操作。Commit 操作用于提交事务并持久化所有更改,Rollback 操作用于撤销当前事务,并且撤销的所有更改都会被回滚。

MongoDB 集群架构

在进行实际的 MongoDB 事务处理时,需要对 MongoDB 的集群架构进行了解。MongoDB 支持两种常见的部署方式:单节点和分布式集群。单节点部署方式指的是将 MongoDB 程序和数据部署在同一主机上;分布式集群部署方式指的是将 MongoDB 数据分布到多个不同的主机上,以实现高可用性、负载均衡和数据复制。

在 MongoDB 分布式集群中,主服务器主要用于写入、检索数据和查询管理工作,而副本集合中的子节点则用于自动处理主服务器失效情况下的容错恢复操作,以保证集群的稳定性和高可用性。MongoDB 分布式架构如下所示:

MongoDB 事务处理实践

准备工作

首先,需要安装 MongoDB 4.0 或 4.2 版本。在本文的实践中,将使用 MongoDB 4.2 版本。安装完毕后,启动 MongoDB 服务:

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

启动服务后,需要创建一个副本集。在 MongoDB shell 中执行如下命令:

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

这个命令会初始化一个副本集,并且当你需要加入新的节点时,可以使用同样的 rs.add() 命令。

实验 1:写事务

在 MongoDB shell 中执行如下代码,创建一个测试数据库和集合,并插入一条测试数据:

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

接着,在 shell 中新开一个会话,同时开启一个事务:

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

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

这里需要注意,MongoDB 原生事务是 session 绑定的,且每个 session 只能绑定一个事务。开启事务后,接下来可以执行 MongoDB 的增、删、改操作:

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

在转账等操作时,如果事务中出现任何一个操作失败,那么操作如果会自动回滚。因此,在本实验中,需要添加一个抛出异常的逻辑:

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

执行完以上操作后,提交事务并结束 session:

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

实验 2:增加事务性安全

除了上述实验的基本写操作外,当在实际应用中执行事务操作时,还需要考虑事务性安全。例如,在实例 1 中的例子中,如果在写入操作期间,另一个 shell 中执行了相同的写操作,那么两个操作将会相互冲突并被回退。在这种情况下,通常需要使用乐观并发控制(Optimistic Concurrency Control,简称 OCC)。

OCC 是指数据库在执行修改操作时,会对记录进行版本控制管理。例如,当一个事务执行写操作时,MongoDB 会记录该事务当前版本的值。在另一个并发事务执行写操作时,MongoDB 会先检查当前事务版本编号是否大于该记录的版本编号,如果大于,则表示当前版本已经过时,需要更新它。在这个过程中,如果两个事务同时操作同一个文档,那么写操作将完成后,版本最新的事务会覆盖版本较旧的事务,并删除该事务的原有所有更改。

假设有两个 shell 会话,session1 和 session2,分别执行以下代码:

session1 执行:

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

session2 执行:

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

在 session2 中通过增加 version 字段属性值来更新文档,MongoDB 会判断 session2 中 MongoClient 内部的版本值(version)比内部储存的文档 version 大了多少,然后更新内部文档的 version 属性,然后更新文档 age 的值。

更加详细的实践操作可参考 MongoDB 官方文档

结论

在本文中,我们介绍了 MongoDB 的事务处理原理和实践,以及 MongoDB 的集群架构和 MongoDB 事务性安全方案。我们希望这篇文章能够为初学者和 MongoDB 专业人士提供参考和指导,帮助他们更好地适应 MongoDB 的事务处理。如果您对 MongoDB 有进一步的疑问,我们建议您查看 MongoDB 官方文档,以获取更加详细的信息和指导。

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


猜你喜欢

  • Jest 测试框架:最佳实践建议

    Jest 是 Facebook 开源的一款 JavaScript 测试框架,它提供了快速、简单、健壮的测试工具。Jest 最初是为 React 应用程序而开发的,但现在已经成为前端开发中最流行的测试框...

    8 天前
  • 解决 Express.js 中出现的 “未捕获的异常” 的问题

    如果你是一个经验丰富的 Express.js 开发人员,你可能已经经历过 “未捕获的异常” 的问题。当应用程序未能捕获异常时,通常会导致服务器崩溃并给用户带来不必要的烦恼。

    8 天前
  • 解决 Kubernetes 集群的瓶颈 —— 容器互通性的探究

    在 Kubernetes 集群中,容器互通性是一个非常重要的概念。容器之间的互通性能够确保服务之间的稳定性和可靠性,提升系统的性能和可扩展性。但在实际操作中,我们经常会遇到容器互通性不稳定、延迟高等问...

    8 天前
  • Socket.io 中如何优化代码实现高效的数据压缩?

    在前端开发中,Socket.io 是一个常用的开源库,主要用于实现实时、双向通信。当我们需要处理大量的数据传输时,如何优化代码实现高效的数据压缩是非常关键的一项技术。

    8 天前
  • 如何在 Cypress 中使用自定义网络代理?

    Cypress 是一个流行的前端自动化测试工具,它提供了强大的 API 来模拟和测试浏览器行为。其中一个重要的功能是能够使用自定义网络代理,使得测试环境更加灵活和可控。

    8 天前
  • C# 程序性能优化的技巧和经验

    在现代互联网时代,随着业务量的不断增长,很多企业的应用也变得越来越复杂。于是,程序性能是软件开发过程中必须要重视的一个方面。当用户面对一个开发漫长且缓慢的应用时,其体验将会非常糟糕,甚至让用户失去对产...

    8 天前
  • 响应式设计中如何实现不同屏幕尺寸之间的跨度适配?

    随着移动设备的普及,我们越来越需要在不同屏幕尺寸下提供优秀的用户体验。响应式设计是现代 Web 开发中不可或缺的一部分,它可以根据不同屏幕尺寸自动调整页面布局,以便用户可以得到最佳的浏览体验。

    8 天前
  • 如何在 Web 组件中使用事件进行通信

    如何在 Web 组件中使用事件进行通信 随着 Web 技术的不断发展,构建复杂的前端应用已经成为了一种普遍的需求。在构建这些应用时,不同组件之间的通信是一个关键的问题。

    8 天前
  • 如何使用 Koa 搭建 Node.js 服务器

    简介 Node.js 是一个使用 JavaScript 构建快速可扩展网络应用程序的平台。它拥有很多流行的框架,其中 Koa 是一个轻量级的 Web 框架,它可以帮助你构建高性能的 Web 应用程序和...

    8 天前
  • Redux-thunk 实现异步 action 请求详解

    在前端开发中,我们经常需要处理异步请求,如加载数据、发送请求等。而 Redux 是一个流行的 JavaScript 应用程序状态管理库,它使用单个不可变状态树来管理整个应用程序的状态。

    8 天前
  • 与 Redux 集成的 React Native 工具链

    React Native 是一种流行的混合移动应用开发框架,它提供了一种简单的方法来创建原生 iOS 和 Android 应用。Redux 是一个 JavaScript 应用程序状态管理工具,它使得状...

    8 天前
  • 前端开发必备——无障碍访问规范介绍

    什么是无障碍访问(Accessibility)? 无障碍访问是指通过一定的技术手段,使得在残障人士、老年人和特殊人群面临的困难得到一定程度的缓解,使得网络资源能够更为广泛地被人类社会所利用和分享,进而...

    8 天前
  • Babel 配置文件.babelrc 中的 env 字段的作用分析

    Babel 是一个广泛使用的 JavaScript 编译器,用于将 ES6+ 的代码转换为 ES5 可以运行的代码。在 Babel 中,你可以使用 .babelrc 配置文件来配置你的编译器。

    8 天前
  • RxJS 在 React Native 开发中使用出现的问题和解决方法

    什么是 RxJS? RxJS 是一种 JavaScript 库,它可以让我们更方便地处理异步数据流。它的核心是 Observables,一个可以发送多个值的对象,以及一些操作符用于处理这些值。

    8 天前
  • ECMAScript 2017 (ES8) 中的异步编程

    在现代 Web 应用程序中,使用异步编程已成为前端开发中不可或缺的一部分。ECMAScript 2017 (ES8) 增加了一些新功能,特别是在异步编程方面,使得 JavaScript 代码更加易于阅...

    8 天前
  • Headless CMS 数据修改如何提高效率

    在 Web 开发中,Headless CMS (无头 CMS) 是一种受欢迎的解决方案,可以帮助开发者更高效地管理内容。Headless CMS 与传统 CMS 不同的地方在于,它们不提供与前端直接交...

    8 天前
  • 如何在 Enzyme 中测试 React 生命周期?

    React 是一个流行的前端框架,其中的生命周期方法是应用程序的核心。而 Enzyme 是一个流行的 React 测试库,它允许开发人员编写和运行测试用例,以确保应用程序的正确性和可靠性。

    8 天前
  • Promise 中的异常处理机制详解

    概述 Promise 是 JavaScript 中常用的一种异步编程方法。它通过链式调用 then 方法,方便地处理异步操作的回调函数。然而,在异步操作中,异常往往是难以避免的。

    8 天前
  • TypeScript 中使用类型保护的指南

    TypeScript 是一种面向对象的 JavaScript 超集,它使我们在开发 Web 前端应用时能够更好地管理大型代码库。当我们在 TypeScript 中使用复杂的类型时,不可避免地会遇到类型...

    8 天前
  • CSS Flexbox:如何解决在 Internet Explorer 中的问题?

    Flexbox 是 CSS3 的布局模块,它使开发人员能够轻松地构建响应式和灵活的网页布局。但是,在 Internet Explorer(IE)浏览器中,Flexbox 的实现存在一些问题。

    8 天前

相关推荐

    暂无文章