mongodb事务简介
这篇文章主要介绍以下几点
- 本地搭建简单的mongodb副本集
- nodejs mongodb事务demo
- mongodb事务的限制
在本地搭建mongodb副本集
- 新建数据库目录和日志目录
mkdir -p ~/srv/mongodb/rs0-0 ~/srv/mongodb/rs0-1 ~/srv/mongodb/rs0-2
mkdir -p ~/srv/mongodb/log0-0 ~/srv/mongodb/log0-1 ~/srv/mongodb/log0-2
- 启动mongodb的三个节点
mongod --replSet rs0 --port 27017 --dbpath ~/srv/mongodb/rs0-0 --logpath ~/srv/mongodb/log0-0/mongo --fork
mongod --replSet rs0 --port 27018 --dbpath ~/srv/mongodb/rs0-1 --logpath ~/srv/mongodb/log0-1/mongo --fork
mongod --replSet rs0 --port 27019 --dbpath ~/srv/mongodb/rs0-2 --logpath ~/srv/mongodb/log0-2/mongo --fork
- 连接任意一个mongodb
mongo --port 27017
- 新建配置并且初始化副本集
rsconf = {
_id: "rs0",
members: [
{
_id: 0,
host: "127.0.0.1:27017"
},
{
_id: 1,
host: "127.0.0.1:27018"
},
{
_id: 2,
host: "127.0.0.1:27019"
}
]
}
rs.initiate(rsconf)
以上四个步骤就完成了mongodb本地副本集环境的搭建,可用 rs.status() 查看副本集的状态以及主节点和分节点
nodejs mongodb事务demo
const MongoClient = require("mongodb").MongoClient;
const client = new MongoClient(
"mongodb://127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019/?replicaSet=rs0"
);
//加这部分是因为mongodb对文件层级发生变动的操作不生效
await db.collection("school").insertOne(
{
name: "Qinghua University",
location: "Beijing"
},
{ session}
);
await db.collection("user").insertOne(
{
name: "lisa",
age: 21
},
{ session }
);
async function start() {
await client.connect();
const session = client.startSession();
await session.startTransaction();
try {
const db = client.db("test");
await db.collection("school").insertOne(
{
name: "Qinghua1 University",
location: "Beijing"
},
{ session}
);
await db.collection("user").insertOne(
{
name: "lisa1",
age: 21
},
{ session }
);
throw new Error('error')
} catch (error) {
const db = client.db("test");
await session.abortTransaction();
session.endSession();
count = await db.collection('school').countDocuments();
console.log(`test-现在school表中有数据${count}条`);
throw error;
}
}
(async () => {
await start();
})();
测试结果count为1,说明在事务里面的插入操作并没有生效
mongodb事务的限制
- 事务只能操作在存在的集合上,集合不存在则不能使用事务,事务可以跨数据库
- 事务不支持在固定大小的集合上
- 事务不支持解释性查询计划(比如explain)
- 使用事务的性能消耗大于不使用事务
- 在事务外的游标不能在事务内查询getMore, 事务内的游标不能在事务外查询getMore
- 事务不能在config,admin,local数据库上使用
- 事务不能在system.*开头的集合上使用
官方建议
事务只是功能的一种加强,但是我们设计数据库结构的时候还是应该按照非范式化的结构去设计,不应该因为有了事务影响我们的数据库结构的设计