MongoDB实现---事务机制

news2025/3/13 8:32:34

事务机制

原子性是MongoDB实现事务的难点,隔离性和持久性则是MongoDB事务机制的亮点

  • ACID支持:由于前面说过MongoDB是基于大数据、提供高度可扩展和高可用;所以其事务机制不仅仅是一般ACID还是结合了BASE理论下的ACID
    • 原子性保证单文档单命令的原子性在4.0 版本之后,MongoDB 开始支持多文档的事务,针对多文档的事务操作,MongoDB 提供 “All or nothing” 的原子语义保证。
    • 一致性:
      • 在分布式BASE理论下,一致性支持是最终一致性所以就会影响到读数据的隔离性
    • 隔离性:
      • MongoDB通过四个隔离级别的读策略读依赖以及MVCC实现分层次的隔离性;
    • 持久性:
      • MongoDB通过确认机制维持持久性(就是写关注)和高性能的权衡,MongoDB支持类似MySQL不丢失的持久性、也支持大概率不丢失或者不考虑丢失的持久性;

原子性

原子性实现

  • 参考MySQL,单机原子性毫无疑问依赖于锁机制回滚日志

    • MongoDB没有回滚日志,但是其实有内存实现了回滚日志功能的、记录update和 insert的链表
    • MongoDB同样使用多粒度封锁协议,最小的粒度是文档(相当于行锁)
  • 单文档事务原子性

    • 单文档事务实现是通过文档加锁+index、oplog、文档数据写入原子性实现的;
    • 单文档事务原子性是MongoDB存储引擎层实现的(这一点类似redis实现事务原子性)
    • 单文档事务原子性本质只支持单命令原子性;
  • 分布式事务(多文档事务)原子性:多文档事务原子性则将**事务的控制交给了应用层,**涉及到很多问题

    • MongoDB默认就是有分布式支持(数据分片),所以需要支持分布式事务
    • 事务副本集需要oplog同步,而多文档事务使用的oplog资源不能占据超过限制(否则副本集将没法增量更新)
    • oplog的全局顺序性和WT实现的事务id没有关联:则导致MongoDB集群看到的事务提交顺序与 WiredTiger 看到的事务提交顺序不一致
    • 多文档事务占据的资源(特别是锁),将可能严重影响性能(由于事务周期长导致长期占用不释放)

多文档原子性

Session和全局时序

Session
  • 为了实现多文档事务,MongoDB首先提出了session的概念;Session即事务的上下文
    • Session保证了会话中事务id递增事务内操作id递增即保存操作id;
    • Session保证因果一致性、会话一致性;
    • Session记录了读写关注;
    • Session记录了读依赖;
全局时序
  • MongoDB通过事务时间戳(transaction timestamp)机制实现全局时序;Server的oplog和WT引擎通过全局时序保证双方事务一致(事务提交和事务回滚);

实现

  • Read as of a timestamp:换句话说就是内存的undo log,即保证:
    • 事务未提交时本事务可见、其他事务根据隔离级别可见;
    • 未提交时,本事务的数据不影响其他事务数据;
    • **由于是内存的undo log,所以如果保留的版本太多,也会对 WT cache 产生很大的压力。**所以MongoDB允许自动更新 oldest timestamp,以删除不必要的版本;
  • 回滚:考虑到副本集,在MongoDB的回滚机制中,副本集不是通过server层操作oplog进行回滚,而是通过存储引擎进行回滚;(或许这也是不需要undo log的原因之一)
    • 本机不仅仅是回滚本事务,而是直接回滚到一个检查点;
    • 副本集同样回滚到该检查点,这样所有数据就快速回滚到一致性状态;
    • 这个检查点依赖于 stable timestampWiredTiger 会确保 stable timestamp 之后的数据不会写到 Checkpoint里,MongoDB 根据复制集的同步状态,**当数据已经同步到大多数节点时(Majority commited),会更新 stable timestamp,因为这些数据已经提交到大多数节点了,一定不会发生 ROLLBACK,**这个时间戳之前的数据就都可以写到 Checkpoint 里了。这要求必须尽快提交stable timestamp以避免oplog过大,内存保存大量版本数据;

持久性

写关注点

  • 写关注点包括:写确认机制(ACK机制:从节点确认、落盘确认)、超时等待

    • {writeConcern : { w: <value>, j: <boolean>, wtimeout: <number> }}
      # w:已传播到指定数量的mongod实例或具有指定标记的mongod实例
      # j:设为1表示确认写入操作的请求已经写入磁盘日志(on-disk journal),也就是下一次Journal log提交。
      # wtimeout选项:指定时间限制,以防止写操作无限期阻塞。
      
  • 4.4后副**本集和分片集群支持设置全局默认的write concern。**没有显示指定写关注的操作将继承全局默认的设置;

  • 允许多粒度的写关注点

  • 实现过程

    • 写请求首先到达主节点
    • 主节点向从节点同步数据
    • 从节点根据落盘确认机制确定发回ACK的时机
    • 主节点:
      • 超时发回失败,进行回滚
      • 收到足够数量的ACK发回成功

隔离性

读关注点

读关注定义了四个隔离级别的读策略

  • local/available: 语义基本一致,都是读操作直接读取本地最新的数据,但不保证该数据已被写入大多数复制集成员。
    • available:无法用于因果关系是一致的会话和事务。
    • local:可用于具有或不具有因果一致的会话和事务。
  • majority:读取 majority committed 的数据,可以保证读取的数据不会被回滚,但是并不能保证读到本地最新的数据。受限于不同节点的复制进度,可能会读取到更旧的值。
    • 副本集必须使用WiredTiger存储引擎
    • 多文档事务中的操作,仅**当事务以写策略“majority”提交时,读策略"majority"才能得以保证 。**否则,读策略"majority"不能保证事务中读取的数据。
  • linearizable读取 majority committed 的数据,但会等待在读之前所有的 majority committed 确认。承诺线性一致性,要求读写顺序和操作真实发生的时间完全一致,既保证能读取到最新的数据,也保证读到数据不会被回滚。
    • 仅为主节点上的读操作指定读策略"linearizable”。
    • 无法用于因果关系是一致的会话和事务。
    • 只对读取单个文档时有效;
  • snapshot:所有的读都将使用同一个快照,直到事务提交为止该快照才被释放,可以避免脏读、不可重复读和幻读;
    • 仅可用于多文档事务。
    • 分片群集上的事务,如果事务中的任何操作涉及已禁用读策略“majority”的分片,则不能对事务使用读策略"snapshot"。

https://blog.csdn.net/zxwjx/article/details/106069585

读依赖readPreference(读策略)

使用

  • 多文档事务: “snapshot”,"local"和 “majority”

  • 单文档事务:除了snapshot;

  • db.collection.find().readConcern(<level>)
    
    image-20220424111956470

一致性

  • journal log

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/433172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

键盘录入及标识符

键盘录入 键盘录入介绍&#xff1a; ●为什么要有键盘录入? 目的&#xff1a;为了让我们操作的数据,变得更加灵活 举例&#xff1a;int a10; 这里a虽然是个变量&#xff0c;但记录的值&#xff0c;却是手动写死的。 提问&#xff1a;能不能让a变量记录的值&#xff0c;灵活…

Elasticsearch-mapping

1.Mapping基本概念 Mapping 也称之为映射&#xff0c;定义了 ES 的索引结构、字段类型、分词器等属性&#xff0c;是索引必不可少的组成部分。 ES 中的 mapping 有点类似与RDB中“表结构”的概念&#xff0c;在 MySQL 中&#xff0c;表结构里包含了字段名称&#xff0c;字段的…

# IMAGE - Image Perimeters

# IMAGE - Image Perimeters ## 题面翻译 ### 描述 给出一张由"x"和"."组成的矩阵。每个"x"可以向上下左右及两个斜对角进行连通&#xff0c;请问由某个点开始的"x"&#xff0c;它所连通的图形的周长为多少。 ### 输入 整个测试有多…

SpringBoot 整合ChatGPT API项目实战

准备工作 &#xff08;1&#xff09;已成功注册 OpenAI 的账号。 &#xff08;2&#xff09;创建 API KEY&#xff0c;这个 API KEY 是用于 HTTP 请求身份验证的&#xff0c;可以创建多个。 注意这个创建之后需要马上复制好保存&#xff0c;关闭弹框之后就看不到了。 &#xf…

excel的导入导出的两种方案 (1 EasyExcel 2 Hutool工具类)

文章目录 前言1 EasyExcel的导入导出导出1 导入依赖2 项目中的CourseEntity实体类3 CoureseVo VO类 (对CourseEntity进行EasyExcel导入导出操作)4 导出代码的编写 并最终测试导出效果5 (前端内容 可选)通过vue按钮点击 导出 导入1 导入依赖 跟导出相同2 创建回调监听器3 编写导…

1、Typescript基础入门与环境搭建

1、开发工具安装与基本配置 1.1、软件下载安装 如果你还没有使用过VSCode&#xff0c;当然先要去官网下载了。下载完成后双击安装&#xff0c;一直下一步即可。 1.2、编辑器汉化 如果你英语不是很好&#xff0c;配置中文版界面是很有必要的&#xff0c;安装个插件就可以了。打…

虚化背景 - 基于镜头模糊滤镜的深度映射

镜头模糊 Lens Blur等滤镜可以使用深度映射 Depth Map来设置像素在视觉上的前后关系。因此&#xff0c;常利用深度映射来创建真实感虚化效果&#xff0c;或者进行超越镜头的任意虚化处理。 ◆ ◆ ◆ 基于 Alpha 通道的深度映射关系 一般可通过建立 Alpha 通道或图层蒙版来创建…

【算法基础】DP第三弹 —— 竞赛篇

一、计数问题 (一)Question 1. 问题描述 2. Input 输入包含多组测试数据。每组测试数据占一行,包含两个整数 a 和 b。当读入一行为 0 0 时,表示输入终止,且该行不作处理。(0 < a, b < 100000000) 3. Output 每组数据输出一个结果,每个结果占一行。每个结果包…

MIPI D-PHYv2.5笔记(21) -- Forward High-Speed Data Transmission Timing

声明&#xff1a;作者是做嵌入式软件开发的&#xff0c;并非专业的硬件设计人员&#xff0c;笔记内容根据自己的经验和对协议的理解输出&#xff0c;肯定存在有些理解和翻译不到位的地方&#xff0c;有疑问请参考原始规范看 DDR时钟差分信号和Data差分信号的时序关系如下图所示…

计及调度经济性的光热电站储热容量配置方法【IEEE30节点】(Matlab代码实现)

&#x1f4a5; &#x1f4a5; &#x1f49e; &#x1f49e; 欢迎来到本博客 ❤️ ❤️ &#x1f4a5; &#x1f4a5; &#x1f3c6; 博主优势&#xff1a; &#x1f31e; &#x1f31e; &#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 …

计算机网络简史

ARPANET的发展 互联网最早的雏形 1931-ARPANET设计 互联网名人堂 1965-packet switching(分包交换) 1969 第一个RFC(Request for Comments)(开始通过APPANET发布)第一个接口信息处理单元&#xff08;Interface Message Processor&#xff09;&#xff08;下图&#xff0c;节…

ChatGPT时代:我们可能站到了自然语言编程的大门口

ChatGPT大火&#xff0c;我现在有种感觉&#xff1a;我们可能站到了自然语言编程的门口&#xff0c;一脚下去&#xff0c;也许能把门踹开。 当然&#xff0c;也可能会踢到一块铁板。 回顾我们的编程之路&#xff0c;基本上就是一个编程门槛不断降低的历史。 最早的一批前辈们…

wireshark抓包工具的使用

前言 ①wireshark是非常流行的网络封包分析软件&#xff0c;功能十分强大。可以截取各种网络封包&#xff0c;显示网络封包的详细信息。 ②使用wireshark的人必须了解网络协议&#xff0c;否则就看不懂wireshark。 ③为了安全考虑&#xff0c;wireshark只能查看封包&#xff…

【Linux】进程通信之管道通信详解

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统编程 一、什么是管道通信 1. 管道通信是一种在进程间传递数据的方法 其实管道通信是Unix中最古老的进程间通信的形式了&#xff1a; 管道通信是一种进程间通信的方式&#xff0c;它可以让一个进…

聚观早报|马斯克将TruthGPT挑战ChatGPT;腾讯披露自研芯片新进展

今日要闻&#xff1a;马斯克将TruthGPT挑战ChatGPT&#xff1b;苹果在印度年销售额近60亿美元&#xff1b;腾讯披露自研芯片沧海最新进展&#xff1b;特斯拉中国工厂普通工人月薪约1万元&#xff1b;飞猪将直接向阿里CEO张勇汇报 马斯克将TruthGPT挑战ChatGPT 4 月 18 日消息&…

Pytorch深度学习笔记(四)梯度向下算法

课程推荐&#xff1a;03.梯度下降算法_哔哩哔哩_bilibili 优化问题&#xff1a;求误差值函数最小的权重w &#xff08;1&#xff09;梯度向下算法思想 在绝大多数的情况下&#xff0c;损失函数是很复杂的&#xff08;比如逻辑回归&#xff09;&#xff0c;根本无法得到参数估计…

从输入url到页面展现(三)通过DNS将域名解析为IP地址以及dns-prefetch的好处

前言 上一节我们用直白的话讲了一下浏览器解析url&#xff0c;而浏览器并不具备发送网络消息的能力&#xff0c;所以委托操作系统发送&#xff0c;而这里的第一步&#xff0c;就是去找到对应web服务器的ip地址&#xff0c;并且对互联网和小子网有了一个认识。 这一节呢说一下我…

换个角度使用Redis去解决跨域存取Session问题

系列文章目录 Redis缓存穿透、击穿、雪崩问题及解决方法 Spring Cache的使用–快速上手篇 分页查询–Java项目实战篇 全局异常处理–Java实战项目篇 该系列文章持续更新&#xff0c;更多的文章请点击我的主页查看哦&#xff01; 文章目录 系列文章目录前言一、遇到的情况二、解…

golang 云效私有模块依赖拉取配置

相关文档 阿里官方文档 go 环境变量配置 export GOPRIVATEcodeup.aliyun.com 凭证设置 非常找重要,https密码配置克隆账户和克隆密码后续会用到 在 可以在 netrc 文件中指定凭据 Linux\MacOS 文件应该存放在执行账户的根目录下&#xff0c;即&#xff1a;~/.netrc sudo v…

SAS 9.3软件安装包下载及安装教程 办公软件

SAS 9.3软件简介&#xff1a; SAS 9.3是目前行业软件中的一款专业的数据统计分析软件&#xff0c;其核心功能包括高级分析、商业智能、客户智能、数据管理、风险管理和欺诈与安全智能六大模块&#xff0c;通过sas软件提供创新的分析、商业智能和数据管理软件与服务&#xff0c…