MongoDB 4.0支持事务了,还有多少人想用MySQL呢?

news2025/1/11 17:57:20

在这里插入图片描述

目录

    • 一、MongoDB 不支持事务?
    • 二、什么是事务?
    • 三、ACID的定义
    • 四、如何使用事务
    • 五、重要参数简介
      • 1、时间限制
      • 2、oplog大小限制
    • 六、连接池 = 数据库连接的缓存
      • 1、MongoDB查询数据五步走
      • 2、MongoDB连接池的参数配置
    • 七、聚合框架
    • 八、MongoDB文档格式设计
      • 1、限制条件
      • 2、查询和写入的访问模式
      • 3、关系类型
      • 4、范式化与反范式化
      • 5、内嵌数据和引用数据对比
      • 6、优化数据操作
    • 九、小结

大家好,我是哪吒,最近项目在使用MongoDB作为图片和文档的存储数据库,为啥不直接存MySQL里,还要搭个MongoDB集群,麻不麻烦?

让我们一起,一探究竟,继续学习MongoDB的事务、连接池以及聚合框架,实现快速入门,丰富个人简历,提高面试level,给自己增加一点谈资,秒变面试小达人,BAT不是梦。

一、MongoDB 不支持事务?

一些第三方文章将 MongoDB 描述成 BASE 数据库。BASE 是指“基本可用、软状态、最终一致”。

但这不是真的,从来都不是!MongoDB 从来都不是“最终一致”的。对主文档的读写是强一致性的,对单个文档的更新始终是原子的。软状态是指需要持续不断的更新数据,否则数据就会过期,但 MongoDB 并非如此。

最后,如果太多的节点不可用,无法达成仲裁,MongoDB 将进入只读状态(降低可用性)。这是有意这么设计的,因为这样可以确保在出现问题时保持一致性。

MongoDB 是一个 ACID 数据库。它支持原子性、一致性、隔离性和持久性。

对单个文档的更新始终是原子的,从 4.0 版本开始,MongoDB 也支持跨多个文档和集合的事务。从 4.2 开始,甚至支持分片集群的跨分片事务。

虽然 MongoDB 支持事务,但在使用它时仍然要谨慎。事务是以性能为代价的,而且由于 MongoDB 支持丰富的分层文档,如果你的模式设计正确,就没有必要经常跨多个文档更新数据。

在这里插入图片描述

二、什么是事务?

事务是数据库中处理的逻辑单元,包括一个或多个数据库操作,既可以是读操作,也可以是写操作,MongoDB支持跨个多操作、集合、数据库、文档和分片的ACID事务。

事务的关键:它要么都成功,要么都失败。

三、ACID的定义

ACID是一个事务所需要具备的一组属性集合。

ACID是原子性atomicity、一致性consistency、隔离性isolation、持久性durability的缩写。

ACID事务可以确保数据和数据库状态的有效性,即使在出现断电或其它错误的情况下也是如此。

原子性确保了事务中的所有操作要么都被执行、要么都不被执行。

一致性确保可如果事务成功,那么数据库将从一个一致性状态转移到下一个一致性状态。

隔离性是允许多个事务同时在数据库中运行的属性。它保证了一个事务不会查看到任何其它事务的部分结果,这意味着多个事务并行运行于依次运行每个事务所获得的结果都相同。

持久性确保了在提交事务时,即使系统发生故障,所有数据也都会保持持久化。

当数据库满足所有这些属性并且只有成功的事务才会被处理时,它就被称为符合ACID的数据库。如果在事务完成之前发生故障,ACID确保不会更改任何数据。

MongoDB是一个分布式数据库,它支持跨副本集和跨分片的ACID事务。网络层增加了额外的复杂性。

四、如何使用事务

MongoDB提供了两种API来使用事务。

  • 第一种与关系型数据库类似(如start_transaction和commit_transaction),称为核心API;
  • 第二种称为回调API,一般推荐使用这种;

核心API不会为大多数错误提供重试逻辑,它要求开发人员为操作、事务提交函数以及所需的任何重试和错误逻辑手动编写代码。

与核心API不同,回调API提供了一个简单的函数,该函数封装了大量的功能,包括启动与指定逻辑会话关联的事务、执行作为回调函数提供的函数以及提交事务。回调API还提供了处理提交错误的重试逻辑。在MongoDB4.2中添加回调API是为了简化使用事务的应用程序开发,也便于添加处理事务错误的应用程序重试逻辑。

核心API和回调API的比较

核心API回调API
需要显示调用才能启动和提交事务启动事务、执行指定操作,然后提交(可在发生错误前终止)
不包含TransientTransactionError和UnknowTransactionCommitResult的错误处理逻辑,而是提供了为这些错误进行自定义处理的灵活性自动为TransientTransactionError和UnknowTransactionCommitResult提供错误处理逻辑
要求为特定事务将显式的逻辑会话传递给API要求为特定事务将显式的逻辑会话传递给API

五、重要参数简介

在MongoDB事务中有两种限制,第一种是时间,控制事务的运行时间、事务等待获取锁的时间以及所有事务运行的最长时间;第二种是MongoDB的oplog条目和单个条目大大小限制;

1、时间限制

事务的默认最大运行时间是1分钟。可以通过修改transactionLifetimeLimitSeconds的限制来增加。对于分片集群,必须在所有分片副本集成员上设置该参数。超过此时间后,事务将被视为已过期,并由定期运行的清理进程终止。清理进程每60秒或transactionLifetimeLimitSeconds/2运行一次,以较小的值为准。

要显式设置事务的时间限制,建议在提交事务时指定maxTimeMS参数。如果maxTimeMS没有设置,那么将使用transactionLifetimeLimitSeconds;如果设置了maxTimeMS,但这个值超过了transactionLifetimeLimitSeconds,那么还是会使用transactionLifetimeLimitSeconds。

事务等待获取其操作所需锁的默认最大时间是 5 毫秒。可以通过修改maxTransactionLockRequestTimeoutMillis参数来控制。如果事务在此期间无法获取锁,则该事务会被终止。

maxTransactionLockRequestTimeoutMillis可以被设置为0、-1或大于0的数字。

  • 设置为0,表示如果事务无法立即获得所需的所有锁,则该事务会被终止;
  • 设置为-1,将使用由maxTimeMS参数所指定的超时时间;
  • 设置为大于0的其它数字,将等待时间配置为该时间,尝试获取锁的等待时间也是该时间,单位秒;

2、oplog大小限制

MongoDB会创建出与事务中写操作数量相同的oplog数目。但是,每个oplog条目必须在16MB的BSON文档大小限制之内。

六、连接池 = 数据库连接的缓存

在最开始接触MongoDB的时候,是通过 MongoDatabase database = new MongoClient("localhost", 27017).getDatabase("test");的方式连接MongoDB。

它会为每个请求创建一个新的连接,然后销毁,一般数据库的连接都是TCP连接,TCP是长连接,如果不断开,就会一直连着。

众所周知,新建一个数据库连接的代价是很大的,复用现有连接才是首选,连接池就是干这个的。

因此当需要新的连接时,就可以复用连接池中缓存的连接了。如果使用得当,连接池可以最大程度的降低数据库的新连接数量、创建频率。

可以通过Mongo.get方法获得DB对象,表示MongoDB数据库的一个连接。默认情况下,当执行完数据库的查询操作后,连接将自动回到连接池中,通过api中的finally方法,将连接归还给连接池,不需要手动调用。

1、MongoDB查询数据五步走

  1. MongoDB Client需要找到可用的MongoDB;
  2. Server MongoDB Client需要和 MongoDB Server建立 Connection;
  3. 应用程序处理线程从 Connection Pool中获取 Connection;
  4. 数据传输(获取连接后,进行 Socket 通信,获取数据);
  5. 断开 Collection;

在这里插入图片描述

2、MongoDB连接池的参数配置

#线程池允许的最大连接数
connectionsPerHost: 40
#线程池中连接的最大空闲时间
threadsAllowedToBlockForConnectionMultiplier: 20
#1、MongoDB Client需要找到可用的MongoDB Server所需要的等待时间
serverSelectionTimeout: 40000
#2、MongoDB Client需要和MongoDB Server建立(new)Connection
connectTimeout: 60000
#3、应用程序处理线程从Connection Pool中获取Connection
maxWaitTime: 120000
#自动重连
autoConnectRetry: true
#socket是否保活
socketKeepAlive: true
#4、数据传输(获取连接后,进行Socket通信,获取数据)
socketTimeout: 30000
slaveOk: true
dbName: ngo
#是否进行权限验证
auth: false
#用户名
username: ngo
#密码
password: 12345678

七、聚合框架

聚合框架是MongoDB中的一组分析工具,可以对一个或多个集合中的文档进行分析。

聚合框架基于管道的概念,使用聚合管道可以从MongoDB集合获取输入,并将该集合中的文档传递到一个或多个阶段,每个阶段对输入执行不同的操作。每个阶段都将之前阶段输出的内容作为输入。所有阶段的输入和输出都是文档,可以称为文档流。

在这里插入图片描述
每个阶段都会提供一组按钮或可调参数,可以通过控制它们来设置该阶段的参数,以执行各种任务。

这些可调参数通常采用运算符的形式,可以使用这些运算符来修改字段、执行算术运算、调整文档形状、执行各种累加任务或其它各种操作。

常见的聚合管道包括匹配match、投射project、排序sort、跳过skip、限制limit。

八、MongoDB文档格式设计

文档中表示数据的方式,在进行文档格式设计时,首先需要了解查询和数据访问的方式。

1、限制条件

比如最大文档大小为16MB。

2、查询和写入的访问模式

通过了解查询的运行时间和频率,识别出最常见的查询,一旦确定了这些查询,就应该尽量减少查询的数量,并在文档设计中确保一起查询的数据存储在同一个文档中。

这些查询中未使用的数据应该存放在不同的集合中。需要考虑是否可以将动态数据(读/写)和静态数据(读)分离开。在进行文档格式设计时,提高最常见查询的优先级会获得最佳的性能。

3、关系类型

根据业务逻辑、文档之间的关系来考虑哪些数据是相关的,确定使用嵌入还是引用。需要弄清楚如何在不执行其它查询的情况下引用文档,以及当关系发生变化时需要更新几个文档。还要考虑数据结构是否易于查询。

4、范式化与反范式化

  • 范式化是指数据分散在多个集合中,在集合之间进行数据的引用;
  • 反范式化会将所有数据嵌入单个文档中;

如何选择范式化与反范式化,范式化的写入速度更快,而反范式化的读取速度更快,因此需要根据应用程序的实际需求进行权衡。

5、内嵌数据和引用数据对比

更适合内嵌数据更适合引用数据
较小子文档较大子文档
数据不经常变更数据经常变更
数据最终一致即可必须保证强一致性
数据通常需要二次查询才能获得数据通常不包含在结果中
快速读取快速写入

6、优化数据操作

优化读操作通常包括正确的索引和单个文档中返回尽可能多的数据;
优化写操作通常包括减少索引数量、尽可能的提高更新效率;

通过删除旧数据进行优化:

第一种方式是通过固定集合实现;

第二种是使用TTL集合。

TTL集合可以更精确的控制删除文档的时间,但在写入量过大的集合中操作速度不够快,通过遍历TTL索引来删除文档。

第三种方式是分库分表。

每个月的文档单独使用一个集合。这种方式实现起来更加复杂,因为需要使用动态集合或数据库名称,可能需要查询多个数据库。

九、小结

  1. MongoDB从4.0开始支持事务了,MongoDB 是一个 ACID 数据库。它支持原子性、一致性、隔离性和持久性。虽然 MongoDB 支持事务,但在使用它时仍然要谨慎。事务是以性能为代价的;
  2. 了解MongoDB了如何使用事务以及它的参数配置方案,达到即插即用的效果;
  3. 对MongoDB查询数据的过程,有了更深层次的理解;
  4. 领悟了MongoDB连接池的意义;
  5. 深刻理解了MongoDB文档格式设计思想;
  6. 总结了MongoDB读写的优化方式;

在这里插入图片描述

Java学习路线总结,搬砖工逆袭Java架构师

10万字208道Java经典面试题总结(附答案)

Java基础教程系列

Java高并发编程系列

数据库进阶实战系列

既然有MySQL了,为什么还要有MongoDB?

一次线上事故,我顿悟了MongoDB的精髓

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

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

相关文章

【八大数据排序法】插入排序法的图形理解和案例实现 | C++

第十六章 插入排序法 目录 第十六章 插入排序法 ●前言 ●认识算法 ●一、插入排序法是什么? 1.简要介绍 2.图形理解 3.算法分析 ●二、案例实现 1.案例一 ●总结 前言 排序算法是我们在程序设计中经常见到和使用的一种算法,它主要是将…

MySQL【left join、right join、inner join】详细用法

参考链接:mysql的left join和inner join的详细用法https://blog.csdn.net/weixin_45906830/article/details/111133181 1. inner join:内连接:显示两个表中有联系的所有数据。 通俗讲:inner join 查找的数据是左右两张表共有的。 …

【C语言练习】字符串旋转你会嘛?

目录🍬题目描述:🍭思路一:🍡代码优化:🍭思路二:🍬题目描述:🍭思路一:🍭思路二:🍬题目描述&#xf…

车辆控制器的 Fail Safe功能介绍

Fail Safe概要 在漆黑的夜路上,一辆开着头灯的汽车经过。 如果控制前照灯的控制器在这种情况下发生故障怎么办? 大灯会熄灭,造成危险吗? 不。 在这种情况下,控制器的“Fail Safe”被激活,前照灯保持其先前的…

企业需要一个数字体验平台(DXP)吗?

数字体验平台是一个软件框架,通过与不同的业务系统喝解决方案集成,帮助企业和机构建立、管理和优化跨渠道的数字体验。帮助企业实现跨网站、电子邮件、移动应用、社交平台、电子商务站点、物联网设备、数字标牌、POS系统等传播内容,除了为其中…

termux入门安装

下载安装 请使用F-Droid 的Termux,GooglePlay的 Termux 可能存在一些问题。 下载地址:https://f-droid.org/en/packages/com.termux/ 下载完成在安卓手机上直接安装Termux的apk文件就可以了。 termux换源 新版本的termux换源一条命令就可以超简单&…

【C++之类和对象】初识类和对象

目录前言一、面向对象VS面向过程二、类三、类的定义四、类的访问限定符五、封装六、C中的用struct和用class定义的类有何不同?七、类的作用域八、类的实例化九、计算类对象的大小十、this指针前言 C是一门面向对象的语言,之前学习的C语言是一种面向过程的…

对epoll的重新学习【附源码】

目录 一、概述 二、使用 三、API 3.1 epoll_create(int size) 3.2 epoll_ctl(int epfd,int op, int fd. struct epoll_event *event) 3.3 epoll_wait(int epfd, struct peoll_event *events, int maxevents, int timeout) 3.4 *ssize_t read(int fd, void buf, size_t c…

python模块之codecs

python 模块codecs python对多国语言的处理是支持的很好的,它可以处理现在任意编码的字符,这里深入的研究一下python对多种不同语言的处理。 有一点需要清楚的是,当python要做编码转换的时候,会借助于内部的编码,转换…

Spark读取Hive数据的两种方式与保存数据到HDFS

Spark读取Hive数据的两种方式与保存数据到HDFS Spark读取Hive数据的方式主要有两种 1、 通过访问hive metastore的方式,这种方式通过访问hive的metastore元数据的方式获取表结构信息和该表数据所存放的HDFS路径,这种方式的特点是效率高、数据吞吐量大、…

规则引擎-drools-4-动态生成drl文档

文章目录drools 引擎工作原理动态生成drl文件示例步骤模板文件 decision_rule_template.drt生成规则文件serviceDecisionNodeFact实体对象生成的drl字符串如下KieHealper 执行动态生成drl文件的原理实际应用过程中,很多时候,规则不是一成不变的&#xff…

54.Isaac教程--RealSense相机

RealSense相机 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录RealSense相机RealsenseCamera Codelet示例应用程序故障排除固件注意事项通过 USB 3.0 电缆使用 USB 3.0 端口x86_64 Linux 主机设置设置电源模型英特尔RealSense 435 摄像头…

分享159个ASP源码,总有一款适合您

ASP源码 分享159个ASP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 159个ASP源码下载链接:https://pan.baidu.com/s/1EaQuRA6mxyylrNWLq8iKVA?pwdaljz 提取码&#x…

springmvc知识巩固

文章目录回顾spring知识前言什么是SpringMVCSpringMVC的优点SpringMVC的常用注解Controller注解的作用ResponseBody注解的作用SpringMVC重定向和转发SpringMVC主要组件SpringMVC的执行流程回顾spring知识 上篇整理了“spring知识巩固”常见面试题,有需要的伙伴请点…

Java基础:源码讲解Collection及相关实现List、Set、Queue

1 缘起 说到Java第一问,很多人的第一反应是三大特性,那么接下来,可能就是集合了。 Collection是Java必知必会,即使没有系统学习,在实际的开发过程中,Collection也是应用最广泛的。 当然,一般的…

ESP-IDF:归并排序测试

ESP-IDF:归并排序测试 /归并排序测试/ void printarry18 (int arr[],int length) { for(int i0;i<length;i) { cout<<arr[i]<<" "; } cout<<endl; } void merge(int arr[],int start, int end, int mid,int * temp) { int length 0;//记录te…

进程间通信之管道(匿名管道与命名管道)

进程间通信之管道进程间通信管道什么是管道管道分类——1.匿名管道匿名管道举例管道的特点管道分类——2.命名管道创建一个命名管道举例命名管道的打开规则匿名管道与命名管道的区别具体使用举例&#xff1a;例子1-用命名管道实现文件拷贝例子2-用命名管道实现server&clien…

POI介绍简介

2.1 POI介绍 Apache POI是用Java编写的免费开源的跨平台的Java API&#xff0c;Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能&#xff0c;其中使用最多的就是使用POI操作Excel文件。 jxl&#xff1a;专门操作Excel maven坐标&#xff1a; <depend…

Linux中安装MySQL及常见问题汇总

一、安装前工作 1、卸载之前的数据库 在安装前需要确定现在这个系统有没有 mysql&#xff0c;如果有那么必须卸载 &#xff08;在 centos7 自带的是 mariaDb 数据库&#xff0c;所以第一步是卸载数据库&#xff09;。 #查看mariadb数据库&#xff1a; rpm -qa | grep maria…

moment.js根据时间戳计算与当前时间相差多少天

Moment旨在在浏览器和Node.js中工作。 所有代码都应该在这两种环境中都有效&#xff0c;并且所有单元测试都在这两种环境中运行。 目前&#xff0c;以下浏览器用于ci系统&#xff1a;Windows XP上的Chrome&#xff0c;Windows 7上的IE 8,9和10&#xff0c;Windows 10上的IE 1…