MONGODB 事务从哪里开始,别再说Mongo没事务了 1 简单操作

bd23042ff4db8e1f580288fd576aeaa9.png

关系型数据库对事务之间的关系是无法拆分的关系,提到关系型数据库最重要的解决的问题就是事务。MONGODB 之前被人一直无法在核心数据库上应用的时,被攻击的问题就是事务,事务中最重要的原子性,在MONGODB的多collection是无法被满足的。

Mongodb的事务是从什么时间开始的,4.0 ,对4.0 到底MONGODB 怎么就支持事务了,这种事务对处理数据和业务有什么帮助。

实际上事务中的原子性,完整性,可持久性,一致性, ACID 在MONGODB4.0 是存在的,这里MONGODB 的事务完成,提到了复制集合,并且是标注粗体的。

c6528dbb87c88150bd8b4106f4c4e9e8.png

多文档操作的事务是跨 “多个操作”,文档, collection, 数据库,这是MONGODB 在4.0后的支持事务提出的概念和可支持的对象。

传统数据库本身我们对事务如果细致的拆分,也是针对,多个操作,多行,多个表,甚至是多个数据库之间(部分RDMBA 也不存在多数据库之间)

进行 ACID 的操作。

这样的意思我可以理解为,MONGODB 引入了 “REDO”, "UNDO", rollback, 在MONGODB 事务内的操作要么全部成功,要么全部失败, 一切都在commit 的时刻后,事务所做的操作才能被展现,也就是说 MONGODB 也支持MVCC 多版本控制了。

往深入去考虑,如果使用MOGNODB的事务操作,也会有大事务,大事务会带来更多的写入成本,所以这里有一个点,我们会用MONGODB 来做大事务吗?MONGODB 文档中通过IMPORTANT 方式注明了

d6b047ebdb8f720c2a9ab588d23412aa.png

其中指明了,事务操作会引起性能方面的消耗(greater performance),并且不能因为有了事务,我们就把mongodb 当传统数据库使用,即使是传统数据库,大事务等等也是我们在使用中避免甚至对有些RDBMS是禁止的。

那我们看看MOGNODB 的事务是怎么操作的,次此操作通过mongo shell完成,如需操作请下载mongoshell 通过 mongosh 完成

1   打开session

session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
2  将需要操作的collection 进行变量绑定
testCollection = session.getDatabase("test").test;
test1Collection = session.getDatabase("test").test1;
3  开始事务标注指定MVCC的模式写模式
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
操作封装,将需要一次执行的事务封装
try {
   testCollection.updateOne( { author: 'Mike' }, { $set: { author: "Tim" } } );
   test1Collection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } );
} catch (error) {
   
   session.abortTransaction();
   throw error;
}

5  提交事务

session.commitTransaction();

关闭session

session.endSession();

执行结果

产生session  ,执行后给session 分配唯一的ID

repl [direct: primary] test> session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
{ id: UUID("c47251d7-b3eb-4f37-8177-19abcbb8cdb3") }

赋值变量,声明要操作的的collections

repl [direct: primary] test> testCollection = session.getDatabase("test").test;
test.test
repl [direct: primary] test> test1Collection = session.getDatabase("test").test1;
test.test1


repl [direct: primary] test> session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );

repl [direct: primary] test> try {
...    testCollection.updateOne( { author: 'Mike' }, { $set: { author: "Tim" } } );
...    test1Collection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } );
... } catch (error) {
...    
...    session.abortTransaction();
...    throw error;
... }

对事务中插入的document 产生  objectId

{
  acknowledged: true,
  insertedId: ObjectId("61b4369ce659f7fa4d869d4e")
}
提交事务后告知事务成功运行,以及事务运行的时间戳
repl [direct: primary] test> session.commitTransaction();
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1639200412, i: 2 }),
    signature: {
      hash: Binary(Buffer.from("a56741588989c0aeafa7506ac4da8ff4471d6d89", "hex"), 0),
      keyId: Long("7040270890788978692")
    }
  },
  operationTime: Timestamp({ t: 1639200412, i: 1 })

b8856296763aa6c1c10296002fc8615a.png

mongodb 操作事务的方式支持 java , python C# 等等具体的版本和语言在下图

4df2a5bf74b46e6511647a1d10399f14.png

本期先到这里,下一期的说说 MONGODB 的事务的参数和注意事项

7e3c7060ebe24fa1f8225b5cf5985d31.png

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Golang 中使用 MongoDB事务,需要使用 MongoDB Go 驱动程序提供的事务 API。下面是一个简单的示例: ```go session, err := client.StartSession() if err != nil { log.Fatal(err) } defer session.EndSession(context.Background()) callback := func(sessCtx mongo.SessionContext) (interface{}, error) { coll1 := client.Database("mydb").Collection("collection1") coll2 := client.Database("mydb").Collection("collection2") err := sessCtx.StartTransaction() if err != nil { return nil, err } // Perform operations on collections inside the transaction _, err = coll1.InsertOne(sessCtx, bson.M{"name": "John"}) if err != nil { sessCtx.AbortTransaction(sessCtx) return nil, err } _, err = coll2.InsertOne(sessCtx, bson.M{"name": "Doe"}) if err != nil { sessCtx.AbortTransaction(sessCtx) return nil, err } err = sessCtx.CommitTransaction(sessCtx) if err != nil { return nil, err } return "success", nil } result, err := session.WithTransaction(context.Background(), callback) if err != nil { log.Fatal(err) } fmt.Println(result) ``` 在此示例中,我们使用 `StartSession()` 方法创建一个 MongoDB 会话对象。然后,我们定义一个回调函数 `callback`,该函数包含了我们想要在事务中执行的操作。在回调函数内部,我们首先使用 `StartTransaction()` 方法开始一个事务。然后,我们执行一些操作(例如,在两个集合中插入文档),并在操作完成后调用 `CommitTransaction()` 方法提交事务。如果事务执行过程中出现任何错误,我们可以调用 `AbortTransaction()` 方法回滚事务。 最后,我们使用 `WithTransaction()` 方法来执行回调函数。如果事务执行成功,`WithTransaction()` 方法将返回回调函数的结果,否则将返回一个错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值