在MongoDB中是否可以在单个事务中执行多个数据库操作?
Is it possible to perform multiple DB operations in a single transaction in MongoDB?
假设我有两个集合 A
和 B
我要进行手术
db.A.remove({_id:1});
db.B.insert({_id:"1","name":"dev"})
我知道 MongoDB 在文档级别保持原子性。是否可以在单个事务中执行上述一组操作?
MongoDB当涉及多个文档时不能保证原子性。
此外,MongoDB 不提供影响多个集合的任何单个操作。
当你想以原子方式做任何你真正想做的事情时,你需要将集合A和B合并为一个集合。请记住 MongoDB 是一个无模式数据库。您可以将不同类型的文档存储在一个集合中,并且可以执行单个原子更新操作,从而对文档执行多个更改。这意味着单个更新可以将 A 类型的文档转换为 B 类型的文档。
要区分同一集合中的不同类型,您可以有一个 type
字段并将其添加到您的所有查询中,或者您可以使用 duck-typing 并通过检查某个字段是否存在来识别类型$exists
.
是的,现在可以了!
MongoDB长期在单个文档级别进行原子写操作。但是,MongoDB 直到 v4.0.0
才支持这种多文档操作的原子性。由于 MongoDB 事务的发布,多文档操作现在本质上是原子的。
但请记住,事务仅在使用 WiredTiger 存储引擎的副本集中受支持,在独立服务器中不受支持(但将来也可能在独立服务器上支持!)
这里有一个mongoshell
的例子,官方文档也提供了:
// 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();
假设我有两个集合 A
和 B
我要进行手术
db.A.remove({_id:1});
db.B.insert({_id:"1","name":"dev"})
我知道 MongoDB 在文档级别保持原子性。是否可以在单个事务中执行上述一组操作?
MongoDB当涉及多个文档时不能保证原子性。
此外,MongoDB 不提供影响多个集合的任何单个操作。
当你想以原子方式做任何你真正想做的事情时,你需要将集合A和B合并为一个集合。请记住 MongoDB 是一个无模式数据库。您可以将不同类型的文档存储在一个集合中,并且可以执行单个原子更新操作,从而对文档执行多个更改。这意味着单个更新可以将 A 类型的文档转换为 B 类型的文档。
要区分同一集合中的不同类型,您可以有一个 type
字段并将其添加到您的所有查询中,或者您可以使用 duck-typing 并通过检查某个字段是否存在来识别类型$exists
.
是的,现在可以了!
MongoDB长期在单个文档级别进行原子写操作。但是,MongoDB 直到 v4.0.0
才支持这种多文档操作的原子性。由于 MongoDB 事务的发布,多文档操作现在本质上是原子的。
但请记住,事务仅在使用 WiredTiger 存储引擎的副本集中受支持,在独立服务器中不受支持(但将来也可能在独立服务器上支持!)
这里有一个mongoshell
的例子,官方文档也提供了:
// 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();