简介

mongodb 的事务是依靠 mongodb 连接的客户端 session 实现,事务执行的流程大致是 建立 session,通过 session startTransaction 启动事务,如果一系列事务都完成,那么 commitTransaction 完成事务操作,并结束当前事务 session;如果一系列事务中有任意事件失败, 那么 abortTransaction 中止事务,内部将已完成的任务回退到修改之前,并结束当前事务 session。

session 

场景描述

当前有两个用户,A 用户有余额 50 软妹币,B 用户有余额 10 软妹币,A 用户给 B 转账 10 ,场景设定 转账很安全,网络也很畅通,没有黑客拦截,没有发生意外,这次转账成功了,这时 A 用户余额剩下40 ,B 用户余额有20。A 感觉很安全,这时又给 B 转账,A 忘记自己余额有多少,给 B 转了 50 ,结果出错了。

在没有事务的情况下,操作数据库是这样的,1.A 账户的余额 -50,2. B 账户增加50. 当 A 余额不足时或在操作 A 账户成功后网络发生错误,B 账户的金额没能正确修改。

在有事务的情况下,即使在操作 A 账户金额后出现错误,则事务会将整个转账过程回退到修改之前。

下载 mongodb4 并解压

https://www.mongodb.com/download-center#community

wget https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-4.0.0.tgztar -xzvf mongodb-osx-ssl-x86_64-4.0.0.tgzcd mongodb-osx-ssl-x86_64-4.0.0

!!! Transaction 只适用复制集 Replica Set, 所以要先搭建mongodb 复制集

启动多个 mongodb 实例

// 创建data目录
mkdir -p data/1301
mkdir -p data/1302
mkdir -p data/1303// 起三个 mongodb 实例
./bin/mongod --replSet shard1  --dbpath=./data/1301 --port=1301
./bin/mongod --replSet shard1  --dbpath=./data/1302 --port=1302
./bin/mongod --replSet shard1  --dbpath=./data/1303 --port=1303

// 配置复制集
./bin/mongo --port 1301
rsconf = {_id: "shard1", members: [ { _id: 0, host: "127.0.0.1:1301" } ] }
rs.initiate( rsconf )
rs.add("127.0.0.1:1302")
rs.add("127.0.0.1:1303")

//查看是否是主节点
rs.isMaster()// 查看复制集状态
rs.status()

编码

mkdir mongodb4
cd mongodb4
npm init
npm i mongodb -S
vi app.js
//app.js(async function()  {// 连接DBconst { MongoClient } = require('mongodb');const uri = 'mongodb://localhost:1301/dbfour';const client = await MongoClient.connect(uri, { useNewUrlParser: true });const db = client.db();await db.dropDatabase();console.log('(1) 首先 删库 dbfour, then 跑路n')// 插入两个账户并充值一些金额await db.collection('Account').insertMany([{ name: 'A', balance: 50 },{ name: 'B', balance: 10 }]);console.log('(2) 执行 insertMany,  A 充值 50, B 充值 10n')await transfer('A', 'B', 10); // 成功console.log('(3) 然后 A 给 B 转账 10n')try {// 余额不足 转账失败console.log('(4) A 再次转账给 B 50n')await transfer('A', 'B', 50);} catch (error) {//error.message; // "Insufficient funds: 40"console.log(error.message)console.log('n(5) A 余额不够啊,所以这次转账操作不成功')}// 转账逻辑async function transfer(from, to, amount) {const session = client.startSession();session.startTransaction();try {const opts = { session, returnOriginal: false };const A = await db.collection('Account').findOneAndUpdate({ name: from }, { $inc: { balance: -amount } }, opts).then(res => res.value);if (A.balance < 0) {// 如果 A 的余额不足,转账失败 中止事务// `session.abortTransaction()` 会撤销上面的 `findOneAndUpdate()` 操作throw new Error('Insufficient funds: ' + (A.balance + amount));}const B = await db.collection('Account').findOneAndUpdate({ name: to }, { $inc: { balance: amount } }, opts).then(res => res.value);await session.commitTransaction();session.endSession();return { from: A, to: B };} catch (error) {// 如果错误发生,中止全部事务并回退到修改之前await session.abortTransaction();session.endSession();throw error; //使其调用者 catch error}}})()

查看结果

node app.js

mongodb 事务_MongoDB4 事务 简单易懂的??相关推荐

  1. MongoDB 4.0 事务实现解析

    上个月底 MongoDB Wolrd 宣布发布 MongoDB 4.0, 支持复制集多文档事务,阿里云数据库团队 研发工程师第一时间对事务功能的时间进行了源码分析,解析事务实现机制. MongoDB ...

  2. mongodb 事务_MongoDB 事务 — 基础入门篇

    MongoDB 单文档原生支持原子性,也具备事务的特性,但是我们说起事务,通常是指在多文档中的实现,因此,MongoDB 在 4.0 版本支持了多文档事务,4.0 对应于复制集的多表.多行,后续又在 ...

  3. 在 MongoDB 上模拟事务操作来实现支付

    我们的产品叫「学海密探」,属于在线教育行业,产品需要有支付功能,然而支付最蛋疼是什么?有人会说是支付宝和微信等支付接口的接入开发!没错,但支付接口的开发算是比较简单的了,我觉得凡是跟钱有关系的操作最重 ...

  4. MongoDB 4.0 事务实现快速上手

    MongoDB 4.0 事务实现快速上手 原创陈小生网易游戏运维平台 陈小生 网易游戏运维工程师,目前主要负责数据库相关的运维工作. MongoDB 4.0 引入了多文档事务的支持,不过目前仅限于单个 ...

  5. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因...

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  6. mysql 事务_MySQL事务

    MySQL中,事务其实是一个最小的,不可分割的工作单元,事务能够保证一个业务的完整性. 比如:我们的银行转账:a给b转账100 a---->-100 b---->+100 update u ...

  7. php怎么创建事务,php事务的实现方法介绍(代码示例)

    本篇文章给大家带来的内容是关于php事务的实现方法介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助.<?php $db = new mysqli("loc ...

  8. 每日一博 - 常见的Spring事务失效事务不回滚案例集锦

    文章目录 事务不生效 方法内部调用 修复方法一 : [新加一个Service方法] 修复方法二:[在该Service类中注入自己] 修复方法三:[通过AopContent类]<---- 推荐 访 ...

  9. 什么是事务、事务的四个特性ACID、不考虑隔离性会导致的三个问题、四种隔离级别

    什么是事务.事务的四个特性ACID.不考虑隔离性会导致的三个问题.四种隔离级别 1 什么是事务 2 事务的四大特性ACID 2.1 原子性 2.2 一致性 2.3 隔离性 2.4 持久性 3 不考虑隔 ...

最新文章

  1. 以安装PyTorch为例说明Anaconda在Windows/Linux上的使用
  2. Windows10 搭建java环境——JDK11的安装与eclipse的安装
  3. 解决 “message“:“An invalid response was received from the upstream server“
  4. 研发过程管理导图-第一稿(转)
  5. 【实习】今日头条【抖音火山】后台开发实习生
  6. php 替换某个字符,php中如何替换字符串中的某个字符-PHP问题
  7. 阿里云 ssh 登陆请使用(公)ip
  8. centos 6.5安装extundelete软件报错
  9. powershell ise好字库和diy配色文件分享
  10. 眼镜蛇效应:事与愿违的经济学教训
  11. Java面试面经大合集(含答案),大厂越来越简单进了,
  12. pgadmin4使用教程
  13. SharePoint下载大文件失败 异常信息: system.OutOfMemoryException
  14. imac下修改本地hosts文件解决react项目中的跨域问题
  15. 电商行业分析指标体系拆解下钻
  16. Network (哈工大网课笔记)
  17. java制作安卓游戏脚本_autoA开源(用java写安卓无障碍脚本)
  18. vue滚动条插件vue-happy-scroll
  19. axios 的 qs库
  20. RabbitMQ-简单模式/工作模式(分发、应答、持久化、不公平分发、发布确认)

热门文章

  1. A Self-Attention Setentence Embedding 阅读笔记
  2. 168. Excel Sheet Column Title
  3. 文巾解题 16. 最接近的三数之和
  4. 文计笔记2: 计算机硬件知识
  5. 早停 tf.keras.callbacks.EarlyStopping() 详解【TensorFlow2入门手册】
  6. 知识点讲解四:栈溢出(stack overflow)问题解决方案
  7. QT写入cmd命令并且调用,以及指定路径新建文件夹
  8. bin二进制文件的运行
  9. 推荐系统之信息茧房问题
  10. linux播放视频的最简单方法