整理mongodb文档:事务(一)

个人博客

整理mongodb文档:事务(一)

原文链接,个人博客 求关注,本文主要讲下怎么在mongose下使用事务,建议电脑端看

文章概叙

本文的开发环境为Nodejs,在‘单机模式’讲解最基本的事务概念。并没有涉及分片以及集群,后续会在介绍完副本集、分片集群之后补充。

关于事务

事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。

单单看概念,是很难有啥理解的。因此,我们先看看事务的四大特征,也就是经常看到的"ACID"。

原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。

隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。

持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。

ACID四个概念,大概理解就可以了。即使是面试,也不一定会拿出来问,但是在这儿,能让我们更好的去理解事务。

基于ACID的四个内容,我们可以举一个经典的例子:转账。
比如a给b转6块钱,步骤就分为了从a的账号扣除6块钱,从b的账户增加6块钱,增加一个从a转1块钱到b的记录。这就是一个事务的流程,也满足了上面所说的四个特征。

由于本博客的编程语言是Javascript,所以本次示范会在Nodejs的环境下开发,对于其他的编程语言,建议在官网上看下

依赖版本

Transactions are new in MongoDB 4.0 and Mongoose 5.2.0. Transactions let you execute multiple operations in isolation and potentially undo all the operations if one of them fails.

这段是在Mongose的网站上搬运下来的,翻译就是:
事务在MongoDB 4.0和Mongoose 5.2.0中新增的。事务允许您独立地执行多个操作。如果其中一个操作失败,则可能会撤消所有操作。

"mongoose": "^7.5.0"

代码示范

首先,按照我们上面所述,我们需要准备一张表,并且将a还有b的钱准备好,各自都准备十块钱给他们

在这里插入图片描述

接下来,我们要写好两条sql。分别是a的账号中减少6块钱,以及b的账号增加6块钱的sql。

正常境况下,这儿可以用聚合,直接使用$add来更改钱数。但是为了演示的方便,手动将其设置为4以及16,不过下方会先人为的制造一个错误。请注意看第二十四行,本应该是16的,但我修改为了’aaa’,这就会导致出现一个错误,但是第一个sql执行成功了,a的数据被更改为了4

const sql = async () => {
// 链接dbconst mongoose = require('mongoose');mongoose.connect('mongodb://localhost:27018/test')// 定义schemaconst schema = new mongoose.Schema({ name: String, count: Number },{ collection: 'test' })// find方法查询await mongoose.model('test', schema).updateOne({ name: 'a' },{"$set": {count: 4}})await mongoose.model('test', schema).updateOne({ name: 'b' },{"$set": { count: 'aaa' }})
}
sql();

直接运行之后,可以看到数据库被更改如下:
在这里插入图片描述

而由于存在错误,导致我们的代码无法更改b的数据
在这里插入图片描述

接下来,在我们恢复数据之后,使用事务来修改下我们的代码。

其中,我们依旧保留了28行的错误,以验证事务的ACID。修改的代码如下。

const sql = async () => {// 链接dbconst mongoose = require('mongoose');mongoose.connect('mongodb://localhost:27018/test')// 创建一个会话const mySession = await mongoose.startSession();//开始事务mySession.startTransaction()// 定义schemaconst schema = new mongoose.Schema({ name: String, count: Number },{ collection: 'test' })try {await mongoose.model('test', schema).updateOne({ name: 'a' },{"$set": {count: 4}}).session(mySession);await mongoose.model('test', schema).updateOne({ name: 'b' },{"$set": { count: 'aaa' }}).session(mySession);// 提交事务await mySession.commitTransaction();console.log('事务结束');} catch (error) {console.log("事务出错了,即将回滚");// 事务回滚await mySession.abortTransaction();}mySession.endSession();}
sql();

一开始,我们创建了一个会话,并开始它的事务。

// 创建一个会话
const mySession = await mongoose.startSession();
//开始事务
mySession.startTransaction()

接着在每一个我们需要绑定的sql中添加到会话去

await mongoose.model('test', schema).updateOne({ name: 'b' },{"$set": { count: 'aaa' }}).session(mySession);

在完成了我们的事务后,我们需要将其提交上去

await mySession.commitTransaction();

如果失败后,我们需要回滚事务,取消掉我们的事务

await mySession.abortTransaction();

最后要有始有终,结束我们的会话

mySession.endSession();

最终的效果如下

在这里插入图片描述

在Mongoose下,事务便是如此,而不会将成功的sql应用到数据库中的原因是事务中的某个文档后来失败,所以该文档中的更改不会保存到MongoDB。并且该函数通知 Mongoose 更改跟踪已回滚,并将事务中更改的所有字段标记为已修改。
至此,在mongodb中的事务,我们已经通过session来实现了。建议自己敲下代码,理解下。

注意点

1.mongodb的事务是4.0以上才支持的,如果项目是很老很老的,建议小心测试再上线。部分老玩家玩mongodb很久的了,会说mongodb没有事务,也是因为4.0以上才有的.
2.在MongoDB 4.0中,仅使用WiredTiger存储引擎的副本集支持事务,如果有条件,个人建议是在4.2以上的版本开发测试。

3.分布式事务是指分片集群和副本集上的多文档事务,从MongoDB 4.2开始,多文档事务(无论是在分片集群上还是副本集上)也称为分布式事务。

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

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

相关文章

ESP32C3 LuatOS RC522②写入字符串

编写了字符串转16进制表函数 -- 将字符串转换为十六进制表 local function stringToHexTable(str)local hexTable {}local maxLength 16 -- 最大长度为16个元素-- 将字符串转换为十六进制for i 1, #str doif i > maxLength thenbreakendlocal hex string.format("…

QT第一天

创建登录界面 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);this->setFixedSize(700,800);//1.实例化一个标签,设置上面界面QLabel *lab1 new QLabel(th…

ElementUI浅尝辄止16:Tag 标签

用于标记和选择。 1.如何使用&#xff1f; 由type属性来选择tag的类型&#xff0c;也可以通过color属性来自定义背景色。<el-tag>标签一</el-tag> <el-tag type"success">标签二</el-tag> <el-tag type"info">标签三</e…

基于Mendix移动原生的离线应用

一、前言 不同行业的企业会有特殊的业务场景&#xff0c;比如某些制造业的企业的工厂是物理隔离的&#xff0c;但工程师需要拿着平板输入很多生产数据&#xff1b;某些煤炭和矿业企业&#xff0c;在实际的工作区都是比较偏远&#xff0c;信号比较差&#xff0c;但是又需要用手…

简单记录下gin中使用中间件记录操作日志

1、直接定义中间件package middlewareimport ("bytes""encoding/json""fmt""github.com/gin-gonic/gin""go.uber.org/zap""io""strconv""strings" )func LoggerMiddleWare() gin.HandlerFunc…

golang中如何判断字符串是否包含另一字符串

golang中如何判断字符串是否包含另一字符串 在Go语言中&#xff0c;可以使用strings.Contains()函数来判断一个字符串是否包含另一个字符串。该函数接受两个参数&#xff1a;要搜索的字符串和要查找的子字符串&#xff0c;如果子字符串存在于要搜索的字符串中&#xff0c;则返…

【python技巧】替换文件中的某几行

【python技巧】替换文件中的某几行 1. 背景描述2. 单行修改-操作步骤3. 多行修改-操作步骤 1. 背景描述 最近在写一个后端项目&#xff0c;主要的操作就是根据用户的前端数据&#xff0c;在后端打开项目中的代码文件&#xff0c;修改对应位置的参数&#xff0c;因为在目前的后…

快速搭建IntelliJ IDEA开发环境的完整教程

添加链接描述 Mysql 安装流程 常见问题 一、环境配置了很久了&#xff0c;不知道装没装过Mysql&#xff1f; 三种方法查&#xff1a;1. cmd中指令where is mysql 2.windows 环境变量中找MYSQL_HOME 3. 打开MySQL的配置文件my.cnf&#xff08;Windows系统路径为C:\ProgramDat…

浏览器安全-同源策略和CORS

同源策略 同源策略是浏览器的一个安全功能&#xff0c;浏览器禁止在当前域读写其他域的资源&#xff0c;如限制跨域发送ajax请求 不受同源策略限制的 1&#xff09;页面中的链接&#xff0c;重定向表单以及表单提交 2&#xff09;跨域资源引入 如script不受跨域限制&#xff0…

Elasticsearch:wildcard - 通配符搜索

Elasticsearch 是一个分布式、免费和开放的搜索和分析引擎&#xff0c;适用于所有类型的数据&#xff0c;例如文本、数字、地理空间、结构化和非结构化数据。 它基于 Apache Lucene 构建&#xff0c;Apache Lucene 是一个全文搜索引擎&#xff0c;可用于各种编程语言。 由于其速…

远程工作面试:特殊情况下的面试技巧

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

【Vue3 知识第四讲】数据双向绑定、事件绑定、事件修饰符详解

文章目录 一、数据双向绑定二、事件绑定详解2.1 **Vue中的事件绑定指令**2.2 **事件函数的调用方式**2.3 **事件函数参数传递** 三、事件修饰符3.1 **Vue中常用的事件修饰符**3.2 **按键修饰符** 四、属性绑定五、类与样式的绑定5.1 class 类的绑定5.2 style 样式绑定 一、数据…

代码随想录二刷day16

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣104. 二叉树的最大深度二、力扣559. N 叉树的最大深度三、力扣111. 二叉树的最小深度三、力扣力扣222. 完全二叉树的节点个数 前言 一、力扣104. 二叉树…

centos7安装php

在 CentOS 7 上使用 Remi 仓库安装 PHP 7.4&#xff0c;您可以按照以下步骤操作 1. 安装 EPEL 仓库&#xff1a; yum install -y epel-release 2. 安装 Remi 仓库&#xff1a; sudo yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm 3. 启用 Remi 仓…

消息队列(MQ)面试

目录 讲一讲MQ 面试官: 在你之前的项目中&#xff0c;你是否使用过消息队列&#xff08;MQ&#xff09;&#xff1f;能详细介绍一下你在项目中如何使用MQ吗&#xff1f; 在用户和用户之间的多对多聊天通信中如何使用&#xff0c;请具体来讲一下。 那你可以讲一下消息的确认…

一文了解Android App Bundle 格式文件

1. Android App Bundle 是什么&#xff1f; 从 2021 年 8 月起&#xff0c;新应用需要使用 Android App Bundle 才能在 Google Play 中发布。 Android App Bundle是一种发布格式&#xff0c;打包出来的格式为aab&#xff0c;而之前我们打包出来的格式为apk。编写完代码之后&a…

Spring中依赖注入的继承bean的细节问题

介绍 有时我们会对一种类型的bean进行继承&#xff0c;在Spring生成bean的时候&#xff0c;返回类型有时是子类类型&#xff0c;有时会父类类型。那么到底在什么情况下用哪种类型呢&#xff1f;肯定有不少人会忽略这点&#xff0c;本篇文章就是把这个细节讲清楚 案例 父类Ba…

uni-app语音转文字功能demo(同声传译)

目录 首先去微信开发者官网申请一下同声传译的插件 微信公众平台 在文件中开始引用&#xff1a; 首先去微信开发者官网申请一下同声传译的插件 微信公众平台 后续使用的时候可以看详情里面的信息进行使用 在文件中开始引用&#xff1a; 注意&#xff01;&#xff01;在这个…

2023年了,java后端还有未来吗?

前言 Java当下确实是比较的内卷&#xff0c;但关键在于个人&#xff0c;可以看看不同地方&#xff08;这里主要举例北上广深一线城市&#xff09;对于Java开发工程师这个职位的具体要求&#xff1a; 在以下北上广深这些一线大城市的面试招聘当中不难看出&#xff0c;凡是工资…

二维码智慧门牌管理系统:让城市管理更智能、便捷

文章目录 前言一、二维码智慧门牌管理系统的特点二、数据集约化与规范化三、管理智能化与长效化四、标识规范化与易维护五、服务多元化与便捷化 前言 随着城市化进程的加速&#xff0c;城市管理面临着越来越多的挑战。为了解决地名地址管理交织错综、地名地址支撑政府管理成效…