MONGODB 谁说MONGODB 没有事务 2 细节与参数

689ab208beb26b0957620539070189ff.png

接上期,MongoDB 的事务操作已经操作了,但细节和参数并没有弄清楚,通过mongodb 的事务操作主要分为以下几个部分

1   Session.startTransaction 

2   Session.commitTransaction

3   Session.abortTransaction

简单的回顾一下,MONGODB 的事务,当一个事务中所有对数据的更改commit 后,外部是可以读取 commit 后的数据,在commit前这些数据在事务之外都不可见。事务中多个操作,其中之一失败,则事务整体失败,则在失败事务之前的操作全部丢弃。这里暂且认为MONGODB 的事务是  READ COMMITED 的方式对我们呈现的。

在昨天的示例里, mongodb 开始一个事务

session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );

需要注意的参数 readConcern  和  writeConcern 

readConcern 可以选择  snapshot  local  majority

这三者的不同点 snapshot 主要针对多文档的事务提交,在readConcern选择了snapshot后,保证了多文档提交后,读取数据是从大多数节点,保证数据的准确性,事务提交时 startTransaction 的readConcern 必须要选择 snapshot,  writeConcern 则也必须选择  marjority 保证写入的事务不会在回滚,确定在大多数节点已经落实。

对于事务的操作总,数据库中config, admin, local  collections 是无效的,system.开头的 collection 也是无效的,对于事务的操作仅仅限于客户自定义的collections。游标如果是在事务内发生的,则只能在事务内部调用,同理事务内部不能调用外部的游标。

在事务内也禁止使用 DDL 操作,如创建一个索引,一个collection  ,一个database ,创建账号 修改密码 等操作,事务内支持 CRUD 的操作。

事务的操作中,如果事务中的一个单独的操作失败了,是不会在进行重试,在事务commit 的阶段提交如果失败了,MONGODB 是会进行重试的。

那么一个完整的事务的提交并且包含重试和报错的程序怎么来操作

下面是一些操作步骤,

1  登陆mongoshell  通过mongosh 登陆 (不知道什么是mongosh 可以去官网看一下)

2   两个

function runTransactionWithRetry(txnFunc, session) {

    while (true) {

        try {

            txnFunc(session);  // performs transaction

            break;

        } catch (error) {

            if ( error.hasOwnProperty("errorLabels") && error.errorLabels.includes("TransientTransactionError")  ) {

                print("TransientTransactionError, retrying transaction ...");

                continue;

            } else {

                throw error;

            }

        }

    }

}

function commitWithRetry(session) {

    while (true) {

        try {

            session.commitTransaction(); 

            print("Transaction committed.");

            break;

        } catch (error) {

            if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes("UnknownTransactionCommitResult") ) {

                print("UnknownTransactionCommitResult, retrying commit operation ...");

                continue;

            } else {

                print("Error during commit ...");

                throw error;

            }

       }

    }

}

事务函数

function updateEmployeeInfo(session) {

    employeesCollection = session.getDatabase("test").test;

    eventsCollection = session.getDatabase("test").test1;

    session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );

    try{

        employeesCollection.insertOne( { employee: 3 }, { $set: { status: "Inactive" } } );

        eventsCollection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } );

    } catch (error) {

        print("Caught exception during transaction, aborting.");

        session.abortTransaction();

        throw error;

    }

    commitWithRetry(session);

——————————————————————————————

执行MONGODB 事务

session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );

try{

   runTransactionWithRetry(updateEmployeeInfo, session);

} catch (error) {

} finally {

   session.endSession();

}

执行后的结果。

具体MONGODB 在事务中可以操作的列表命令 在下方网址可以查询详细信息

Transactions and Operations — MongoDB Manual

b5a722921dbb2144517abf26494e63c8.png

后面还会关注MONGODB 的事务,以及一些案例。

cb146db0c90709ebba301d136b8ecfca.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值