0
点赞
收藏
分享

微信扫一扫

vs code调试rust乱码问题解决方案

捡历史的小木板 2023-09-10 阅读 12

个人博客

整理mongodb文档:事务(一)

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

文章概叙

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

关于事务

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

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

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

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

依赖版本

这段是在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 () => {
// 链接db
    const mongoose = require('mongoose');
    mongoose.connect('mongodb://localhost:27018/test')
    // 定义schema
    const 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 () => {
    // 链接db
    const mongoose = require('mongoose');
    mongoose.connect('mongodb://localhost:27018/test')
    // 创建一个会话
    const mySession = await mongoose.startSession();
    //开始事务
    mySession.startTransaction()
    // 定义schema
    const 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开始,多文档事务(无论是在分片集群上还是副本集上)也称为分布式事务。

举报

相关推荐

0 条评论