假设我有两个集合A
和B
我想执行一项操作
db.A.remove({_id:1});
db.B.insert({_id:"1","name":"dev"})
我知道MongoDB在文档级别保持原子性。是否可以在单个事务中执行上述操作集?
答案 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();
答案 1 :(得分:1)
当涉及多个文档时,MongoDB无法保证原子性。
此外,MongoDB不提供任何影响多个集合的操作。
当你想以原子方式做任何你想要做的事情时,你需要将集合A和B合并到一个集合中。请记住,MongoDB是一个无模式数据库。您可以将不同类型的文档存储在一个集合中,并且可以执行单个原子更新操作,以对文档执行多个更改。这意味着单个更新可以将类型A的文档转换为类型B的文档。
要区分相同集合中的不同类型,您可以拥有type
字段并将其添加到所有查询中,或者您可以使用duck-typing并通过检查某个字段{{来识别类型1}}。