事务
概述
在这份指南中,您可以了解如何使用 PyMongo 驱动程序执行 事务。事务允许您运行一系列操作,直到事务提交之前不会更改任何数据。如果事务中的任何操作返回错误,驱动程序将取消事务并丢弃所有更改的数据,这些更改数据在它们变得可见之前都不会被应用。
在 MongoDB 中,事务在逻辑 会话 中运行。会话是一组相关的读取或写入操作,您打算依次运行这些操作。会话为操作组启用 因果一致性,并允许您以 ACID 兼容的事务 运行操作,这种事务满足原子性、一致性、隔离性和持久性的期望。MongoDB 保证事务操作涉及的数据保持一致性,即使操作遇到意外错误。
使用 PyMongo 时,您可以从MongoClient
实例创建一个新的 ClientSession
类型。我们建议您重复使用您的 MongoClient
来进行多个会话和事务,而不是每次都创建一个新的客户端。
警告
仅使用创建它的 MongoClient
(或相关的 MongoDatabase
或 MongoCollection
)与 ClientSession
一起使用。使用与不同 MongoClient
一起使用的 ClientSession
将导致操作错误。
示例数据
本指南中的示例使用来自Atlas 示例数据集 的 sample_restaurants.restaurants
集合。要了解如何创建免费的 MongoDB Atlas 集群并加载示例数据集,请参阅
方法
使用 start_session()
方法启动会话后,您可以通过以下由返回的 ClientSession
提供的方法来管理会话状态。
方法 | 描述 |
---|---|
start_transaction() | 在此会话上启动一个新的事务,配置了给定的选项。如果会话中已有正在进行的交易,则返回错误。有关此方法的更多信息,请参阅服务器手册中的 startTransaction() 页面。 参数: read_concern 、write_concern 、read_preference 、max_commit_time_ms 返回类型: 上下文管理器 |
abort_transaction() | 结束此会话的当前事务。如果没有活动事务或事务已提交或结束,则返回错误。有关此方法的更多信息,请参阅服务器手册中的 abortTransaction() 页面。 |
commit_transaction() | 提交此会话的当前事务。如果没有活动事务或事务已结束,则返回错误。有关此方法的更多信息,请参阅服务器手册中的 commitTransaction() 页面。 |
with_transaction() | 在此会话上启动一个事务,并运行一次 callback ,然后提交事务。如果发生异常,此方法可能会重试提交或整个事务,这可能会通过一次对 with_transaction() 的调用多次调用回调。参数: callback 、read_concern 、write_concern 、read_preference 、max_commit_time_ms 返回值: callback 函数的结果 |
end_session() | 结束此会话。如果已开始事务,则此方法将中止它。如果没有要结束的活动会话,则返回错误。 |
ClientSession
还具有检索会话属性和修改可变会话属性的方法。有关这些方法的更多信息,请参阅 API 文档。
示例
以下示例展示了如何通过以下步骤创建会话、创建事务并提交多文档插入操作:
使用客户端的
start_session()
方法创建会话。使用
with_transaction()
方法启动事务。插入多个文档。当
with_transaction()
方法执行插入操作并提交事务时,该方法将运行。如果任何操作导致错误,with_transaction()
将取消事务。此方法确保在块退出时会话正确关闭。使用
client.close()
方法关闭与服务器的连接。
# Establishes a connection to the MongoDB server client = MongoClient("<connection string>") # Defines the database and collection restaurants_db = client["sample_restaurants"] restaurants_collection = restaurants_db["restaurants"] # Function performs the transaction def insert_documents(session): restaurants_collection_with_session = restaurants_collection.with_options( write_concern=WriteConcern("majority"), read_concern=ReadConcern("local") ) # Inserts documents within the transaction restaurants_collection_with_session.insert_one( {"name": "PyMongo Pizza", "cuisine": "Pizza"}, session=session ) restaurants_collection_with_session.insert_one( {"name": "PyMongo Burger", "cuisine": "Burger"}, session=session ) # Starts a client session with client.start_session() as session: try: # Uses the with_transaction method to start a transaction, execute the callback, and commit (or abort on error). session.with_transaction(insert_documents) print("Transaction succeeded") except (ConnectionFailure, OperationFailure) as e: print(f"Transaction failed: {e}") # Closes the client connection client.close()
如果您需要更多控制事务,可以使用 start_transaction()
方法。您可以使用此方法以及前文所述的 commit_transaction()
和 abort_transaction()
方法来手动管理事务生命周期。
更多信息
要了解更多关于本指南中提到的概念,请参阅服务器手册的以下页面
要了解更多关于ACID兼容性的信息,请参阅MongoDB网站上关于数据库管理系统中的ACID属性是什么?的文章。
API 文档
要了解更多关于本指南中讨论的任何类型或方法的信息,请参阅以下 API 文档