You can use transactions to enforce consistency between collections that contain duplicated data. Transactions update multiple collections in a single atomic operation.您可以使用事务来强制包含重复数据的集合之间的一致性。事务在单个原子操作中更新多个集合。
Use transactions to enforce consistency if your application must always return up-to-date data and can tolerate potential negative performance impact during periods of heavy reads.如果应用程序必须始终返回最新数据,并且可以在大量读取期间容忍潜在的负面性能影响,则使用事务来强制一致性。
Transactions might not be as performant as other methods of enforcing data consistency. Read performance might be negatively impacted while a transaction is open. However, transactions ensure that the data read by the client is always current.事务的性能可能不如其他强制数据一致性的方法。事务打开时,读取性能可能会受到负面影响。但是,事务确保客户端读取的数据始终是最新的。
About this Task关于此任务
To use transactions, you must connect to a replica set or sharded cluster. You cannot use transactions on standalone deployments.要使用事务,您必须连接到副本集或分片集群。您不能在独立部署上使用事务。
Before you Begin开始之前
Review the different methods to enforce data consistency to ensure that transactions are the best approach for your application. For more information, see Data Consistency.审查强制数据一致性的不同方法,以确保事务是应用程序的最佳方法。有关详细信息,请参阅数据一致性。
Steps步骤
The following example enforces data consistency in an e-commerce application. The example schema duplicates product information in the 以下示例强制电子商务应用程序中的数据一致性。示例模式复制了products and sellers collections. This schema design optimizes queries for both products and sellers.products和sellers集合中的产品信息。这种模式设计优化了产品和卖家的查询。
When a product is updated, such as when its price changes, it is critical that the price is consistent in the 当产品更新时,例如当其价格发生变化时,products and sellers collections. Therefore, transactions are a reasonable method to enforce data consistency in this application.products和sellers集合中的价格保持一致至关重要。因此,事务是在此应用程序中强制数据一致性的合理方法。
Create the products collection创建产品集合
use test
db.products.insertMany(
[
{
sellerId: 456,
name: "sweater",
price: 30,
rating: 4.9
},
{
sellerId: 456,
name: "t-shirt",
price: 10,
rating: 4.2
},
{
sellerId: 456,
name: "vest",
price: 20,
rating: 4.7
}
]
)Create the sellers collection创建卖家集合
use test
db.sellers.insertOne(
{
id: 456,
name: "Cool Clothes Co",
location: {
address: "21643 Andreane Shores",
state: "Ohio",
country: "United States"
},
phone: "567-555-0105",
products: [
{
name: "sweater",
price: 30
},
{
name: "t-shirt",
price: 10
},
{
name: "vest",
price: 20
}
]
}
)Configure a transaction to handle updates配置事务以处理更新
Note
The following example uses a transaction in 以下示例使用mongosh. To see transaction examples for MongoDB drivers, see Transactions.mongosh中的事务。要查看MongoDB驱动程序的事务示例,请参阅事务。
The following example uses a transaction to update the price of the 以下示例使用事务来更新vest in both the products and sellers collections:products和sellers集合中vest(背心)的价格:
// Start a session启动会话
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
productsCollection = session.getDatabase("test").products;
sellersCollection = session.getDatabase("test").sellers;
// Start a transaction启动事务
session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } );
// Operations inside the transaction事务内部的操作
try {
productsCollection.updateOne(
{ sellerId: 456, name: "vest" },
{ $set: { price: 25 } }
);
sellersCollection.updateOne(
{ },
{ $set: { "products.$[element].price": 25 } },
{ arrayFilters: [ { "element.name": "vest" } ] }
);
} catch (error) {
// Cancel transaction on error错误时取消事务
session.abortTransaction();
throw error;
}
// Commit the transaction using write concern set at transaction start使用事务开始时设置的写入关注提交事务
session.commitTransaction();
session.endSession();Results结果
To confirm that the price was updated and that the data is consistent, query the 要确认价格已更新且数据一致,请查询products and sellers collections.products和sellers集合。
Query the Products Collection查询产品集合
db.products.find( { sellerId: 456, name: "vest" } )
Output:输出:
[
{
_id: ObjectId("64d506c3ddebf45734d06c58"),
sellerId: 456,
name: 'vest',
price: 25,
rating: 4.7
}
]Query the Sellers Collection查询卖家收款
db.sellers.find( { id: 456, "products.name": "vest" } )
Output:输出:
[
{
_id: ObjectId("64d516d9ddebf45734d06c5a"),
id: 456,
name: 'Cool Clothes Co',
location: {
address: '21643 Andreane Shores',
state: 'Ohio',
country: 'United States'
},
phone: '567-555-0105',
products: [
{ name: 'sweater', price: 30 },
{ name: 't-shirt', price: 10 },
{ name: 'vest', price: 25 }
]
}
]Learn More了解更多
To see other ways to enforce data consistency, see:要查看强制数据一致性的其他方法,请参阅: