mongodb有没有事务
今天就跟大家聊聊有关mongodb有没有事务,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
MongoDB 4.0 引入的事务功能,支持多文档 ACID 特性,例如使用 mongo shell 进行事务操作。
>s=db.getMongo().startSession()session{"id":UUID("3bf55e90-5e88-44aa-a59e-a30f777f1d89")}>s.startTransaction()>session.getDatabase("mytest").coll01.insert({x:1,y:1})WriteResult({"nInserted":1})>session.getDatabase("mytest").coll02.insert({x:1,y:1})WriteResult({"nInserted":1})>s.commitTransaction()(或者s.abortTransaction()回滚事务)
支持 MongoDB 4.0 的其他语言 Driver 也封装了事务相关接口,用户需要创建一个 Session,然后在 Session 上开启事务,提交事务。例如:
python 版本
withclient.start_session()ass:s.start_transaction()collection_one.insert_one(doc_one,session=s)collection_two.insert_one(doc_two,session=s)s.commit_transaction()
java 版本
try(ClientSessionclientSession=client.startSession()){clientSession.startTransaction();collection.insertOne(clientSession,docOne);collection.insertOne(clientSession,docTwo);clientSession.commitTransaction();}
一、预备工作
1、MongoDB需要4.0版本+
2、需要自己搭建MongoDB复制集,单个mongodb server 不支持事务。
事务原理:mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。mongodb各个节点常见的搭配方式为:一主一从、一主多从。主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
3、搭建复制集步骤
启动mongo主节点实例,bin目录下命令窗口执行,复制集命名为doudou, 8080端口的数据库文件位于db1目录下,--dbpath=路径写自己的,启动后勿关闭命令窗口
mongod--replSetdoudou--dbpath=E:\mongoDb\data\db1--port=8080
启动mongo从节点实例,bin目录下命令窗口执行,复制集命名为doudou, 8081端口的数据库文件位于db2目录下,--dbpath=路径写自己的,启动后勿关闭命令窗口
mongod--replSetdoudou--dbpath=E:\mongoDb\data\db2--port=8081
两个节点启动后,bin目录下打开命令窗口,连接主节点
mongo--port=8080
命令初始化
rs.initiate()
两个节点启动后,bin目录下打开命令窗口,连接主节点
mongo--port=8080
成功后如图:
命令初始化
rs.initiate()
效果如图:
成功的结果是(ok项是1,失败是0)
查看是否是主节点 rs.isMaster()
查看复制集状态 rs.status()
初始化配置
rs.conf()
向主节点添加从节点
rs.add("localhost:8081")
查看主节点状态
rs.status()
复制集配置完成。
二、复制集中的坑点
1、需使用mongoose.connection对集合进行事务操作,其他model的CRUD方法不支持事务。
mongoose.connection.collection('集合名')//注:集合名需要小写且加s,如model为Cat,集合名这里应写为cats
2、触发Schema定义的中间件默认值需要构造model实例
constCatSchema=newSchema({name:{type:Stringdefault:'cat'},created:{ type:Date, default:Date.now }})constCat=mongoose.model('Cat',CatSchema)newCat()//触发中间件
3、insertOne,findOneAndUpdate等方法对数据的新增,需上面第二点进行依赖,否则直接insertOne插入一条数据,定义的默认值不会触发,如created字段,chema内部定义的type:Schema.ObjectId的相应字段,insertOne插入后都会变成字符串类型,不是Schema.ObjectId类型。
//解决方式//新增constCat=newCat();constdata={name:5}for(letkeyindata){Cat[key]=data[key];}db.collection('cats').insertOne(Cat);//查询修改db.collection('cats').findOneAndUpdate({_id:mongoose.Types.ObjectId(你的id)},{$set:{name:修改值}})
三、开始事务
注:以下皆为egg实例代码
封装获取session函数
//获取session,回滚事务asyncgetSession(opt={readConcern:{level:"snapshot"},writeConcern:{w:"majority"}}){const{mongoose}=this.appconstsession=awaitmongoose.startSession(opt);awaitsession.startTransaction();returnsession}
执行事务逻辑
const{mongoose}=this.ctx.app;constsession=awaitthis.ctx.getSession();constdb=mongoose.connection;try{constdata=this.ctx.request.body;constCat=newthis.ctx.model.Cat();for(letkeyindata){Cat[key]=data[key]}awaitdb.collection('cats').insertOne(Cat,{session});//提交事务awaitsession.commitTransaction();this.ctx.end();}catch(err){//回滚事务awaitsession.abortTransaction();this.ctx.logger.error(newError(err));}finally{awaitsession.endSession();}
看完上述内容,你们对mongodb有没有事务有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。