是否可以在MongoDB中的单个事务中执行多个数据库操作?

时间:2015-05-06 08:28:03

标签: mongodb transactions atomicity

假设我有两个集合AB

我想执行一项操作

db.A.remove({_id:1});
db.B.insert({_id:"1","name":"dev"})

我知道MongoDB在文档级别保持原子性。是否可以在单个事务中执行上述操作集?

2 个答案:

答案 0 :(得分:2)

是的,现在你可以了!

MongoDB 长期以来一直在单个文档级别进行原子写操作。但是,在多文档操作的情况下,MongoDB 直到 v4.0.0 才支持这种原子性。由于 MongoDB 事务的发布,多文档操作现在本质上是原子的。

但请记住,事务仅在使用 WiredTiger 存储引擎的副本集中支持,在独立服务器中不支持(但将来也可能在独立服务器上支持!)

这是官方文档中也提供的 mongo shell 示例:

// Start a session.
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );

employeesCollection = session.getDatabase("hr").employees;
eventsCollection = session.getDatabase("reporting").events;

// Start a transaction
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );

//As many operations as you want inside this transaction
try {
   employeesCollection.updateOne( { employee: 3 }, { $set: { status: "Inactive" } } );
   eventsCollection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } );
} catch (error) {
   // Abort transaction on error
   session.abortTransaction();
   throw error;
}

// Commit the transaction using write concern set at transaction start
session.commitTransaction();

session.endSession();

我建议您阅读thisthis以更好地了解如何使用!

答案 1 :(得分:1)

当涉及多个文档时,MongoDB无法保证原子性。

此外,MongoDB不提供任何影响多个集合的操作。

当你想以原子方式做任何你想要做的事情时,你需要将集合A和B合并到一个集合中。请记住,MongoDB是一个无模式数据库。您可以将不同类型的文档存储在一个集合中,并且可以执行单个原子更新操作,以对文档执行多个更改。这意味着单个更新可以将类型A的文档转换为类型B的文档​​。

要区分相同集合中的不同类型,您可以拥有type字段并将其添加到所有查询中,或者您可以使用duck-typing并通过检查某个字段{{来识别类型1}}。