mongo 4 中事务的简单学习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgrbsbf/article/details/84143478

我也的mongo的版本是4.0.4

这是一个新增的功能,以前不支持事务

1. run-rs与replica set

事务操作如果连接的mongo不是副本集的话,会报错:

Transaction numbers are only allowed on a replica set member or mongos

所以还要想办法弄个副本集出来,为了方便,使用了run-rs这个npm包,开启副本集之后如下:

root@1234567890:/# ps aux|grep mongo
root        346  0.0  0.0 755300 34428 pts/13   SLl+ Nov15   0:02 ./mongo
root        432  0.0  0.0 755300 32736 pts/19   SLl+ Nov15   0:02 ./mongo
root       1226  0.9  0.0 1390648 116736 pts/31 Sl+  08:21   0:30 /usr/local/lib/node_modules/run-rs/4.0.4/mongod --po
rt=27017 --dbpath=//./data/27017 --bind_ip=127.0.0.1 --replSet=rs
root       1256  0.9  0.0 1307828 116440 pts/31 Sl+  08:21   0:30 /usr/local/lib/node_modules/run-rs/4.0.4/mongod --po
rt=27018 --dbpath=//./data/27018 --bind_ip=127.0.0.1 --replSet=rs
root       1286  0.9  0.0 1340556 116796 pts/31 Sl+  08:21   0:31 /usr/local/lib/node_modules/run-rs/4.0.4/mongod --po
rt=27019 --dbpath=//./data/27019 --bind_ip=127.0.0.1 --replSet=rs
root       1449  0.0  0.0 755292 33988 pts/31   Sl+  08:21   0:00 /usr/local/lib/node_modules/run-rs/4.0.4/mongo --qui
et
rs:PRIMARY> db.sihwu1.find()
{ "_id" : ObjectId("5bee8ddca033cc776040bc2f"), "name" : "000" }
{ "_id" : 0 }

目前集合sihwu1中有两个文档。
尝试在一个事务中进行如下操作:

  1. 删除name是"000"的文档
  2. 插入一个新文档,其name属性是’000’
  3. 插入一个新文档,其_id属性是0

上述的第三步会产生问题,以为集合sihwu1中已经有一个文档的_id是0了,所以整个事务执行完毕之后第一步第二步第三步都不会生效。下面上代码:

const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://127.0.0.1:27017/?replicaSet=rs";
const dbname = 'testba';

//  Transaction numbers are only allowed on a replica set member or mongos
// Multi-document transactions are available for replica sets only.

async function test() {
    const client = await MongoClient.connect(url);
    const db = client.db(dbname);
    const session = client.startSession();
    try {
        await session.startTransaction();
        await db.collection("sihwu1").deleteMany({
            name: '000'
        }, {session});
        await db.collection("sihwu1").insertOne({
            name: '000', password: '123456'
        }, {session});
        await db.collection("sihwu1").insertOne({
            _id: 0,
            name: '000'
        }, {session});
        await session.commitTransaction();
    } catch (e) {
        console.log('e', e);
        await session.abortTransaction();
    } finally {
        session.endSession();
        console.log('finally');
    }
}

test();

控制台输出结果如下:

e { MongoError: E11000 duplicate key error collection: testba.sihwu1 index: _id_ dup key: { : 0 }

查看sihwu1集合,看到:

rs:PRIMARY> db.sihwu1.find()
{ "_id" : ObjectId("5bee8ddca033cc776040bc2f"), "name" : "000" }
{ "_id" : 0 }
rs:PRIMARY>

猜想得到验证。

参考文献:
https://www.queryxchange.com/q/27_51461952/mongodb-v4-0-transaction-mongoerror-transaction-numbers-are-only-allowed-on-a-replica-set-member-or-mongos/

https://docs.mongodb.com/manual/core/transactions/index.html

猜你喜欢

转载自blog.csdn.net/zgrbsbf/article/details/84143478