MongoDB 4.0事务:ACID读写?

8

MongoDB 4.0推出了多文档事务。我的问题是,这是否可以实现与SQL存储过程相同的功能?

使用情况如下:

  1. 锁定集合
  2. 从集合中读取
  3. 根据2中的结果写入集合
  4. 提交/中止

通常,常见的数据库驱动程序会将您发出的任何命令堆叠起来,直到您调用提交,然后在数据库机器上依次运行它们。因此,在实际提交事务之前,我在服务器代码中运行的任何读操作都将被运行,并且因此其他连接可能会更改读写操作之间的数据。

MongoDB 4.0是否涵盖此功能?


5
这个与主题无关吗?我并没有要求推荐。 - ThatBrianDude
你正在询问尚不存在的东西。它如何符合主题要求 - Alex Blex
2
他们已经存在了一个多星期了。在你发表评论之前,请先做好研究工作。请查看:https://www.mongodb.com/blog/post/mongodb-40-release-candidate-0-has-landed - ThatBrianDude
2
此外,即使某些答案仍处于测试阶段或尚未发布,仍有人可能知道答案。为什么会被认为是离题呢? - ThatBrianDude
2
请取消您的踩以提高可见性。 - ThatBrianDude
我为了更清晰而编辑了我的问题。 - ThatBrianDude
1个回答

11
“MongoDB 4.0是否支持这个功能?” 短答案是可以保证原子性。 在MongoDB中,事务(也称为多文档事务)与会话相关联。也就是说,您为会话启动一个事务。在任何给定时间,您最多可以为会话打开一个事务。 您不能锁定整个集合以进行写操作。您可能需要创建多个事务,以确保写入不会在进程之间交错/覆盖。MongoDB使用乐观锁定而不是悲观锁定。 “因此,在我的服务器代码中运行的任何读取操作都是在实际提交事务之前运行的,因此其他连接可能会在读取和写入操作之间更改数据” 同样适用于MongoDB多文档事务。例如,使用mongo shell
s1 = Mongo().startSession() 
sessionTest = s1.getDatabase("databaseName").test;
s1.startTransaction() 
sessionTest.find({a:"foo"})
> {_id: ObjectId(..), a:"foo", b:1}

// Let's update the record outside of the session (i.e. another process)
db.test.update({a:"foo"}, {$set:{b:2}})

sessionTest.update({a:"foo"}, {$set:{b:9}})
// You'll get a WriteConflict error because the the document has been modified outside of the session. 

同时需要注意的是,当事务打开时,事务中进行的数据更改对事务外不可见。
  • 当事务提交时,所有数据更改都会被保存并在事务外部可见,然后事务结束。
  • 当事务中止时,由事务中写入所做的所有数据更改都会被丢弃而从未变得可见,然后事务结束。

另请参阅原子性示例

值得注意的是,MongoDB是一种分布式数据库,因此您还需要了解不同的一致性选项。您可以根据用例在启动Session.startTransaction()时指定这些选项:

多文档事务支持读取首选项主要,并且给定事务中的所有操作必须路由到同一成员。

您可能还会对工程粉笔谈话:MongoDB事务视频感兴趣,其中包含有关MongoDB事务背后的一些技术解释。


太棒了!是否会有重试交易直到成功的选项? - ThatBrianDude
3
嗨 @ThatBrianDude,没有自动重试的选项。您需要自己实现该逻辑。主要原因是根据用例,不是所有事务都应/可以重试。请注意,在事务中写入不支持“retryableWrite”。 - Wan B.
为什么不提供一个可选参数来完成这个操作呢?尽管如此,我还是很喜欢它。 - ThatBrianDude

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接