事务
概述
在本指南中,您可以学习如何使用MongoDB Go驱动程序执行 事务。事务 允许您运行一系列操作,直到事务提交之前不会更改任何数据。如果事务中的任何操作返回错误,驱动程序将取消事务并丢弃所有更改,这些更改永远不会变得可见。
在MongoDB中,事务在逻辑 会话 中运行。一个 会话 是一组相关读取或写入操作,您打算按顺序执行。会话使一组操作具有 因果一致性,或者允许您执行 ACID事务。MongoDB保证参与事务操作的数據保持一致,即使在操作遇到意外错误的情况下也是如此。
当使用Go驱动程序时,您可以从Client
实例创建一个新的 Session
类型。我们建议您重用客户端以进行多个会话和事务,而不是每次都实例化一个新的客户端。
警告
请仅使用创建它的 Client
(或相关的 Database
或 Collection
)使用 Session
。使用不同 Client
的 Session
将导致操作错误。
警告
Session
的实现不适合由多个 goroutines 并发使用。
方法
使用StartSession()
方法启动会话后,您可以使用Session
接口提供的方法来修改会话状态。以下表格描述了这些方法
方法 | 描述 |
---|---|
StartTransaction() | 在此会话上启动一个新的交易,配置给定的选项。如果会话中已有正在进行的交易,则返回错误。有关此方法的更多信息,请参阅服务器手册中的startTransaction()页面。 参数: TransactionOptions 返回类型: error |
AbortTransaction() | 结束此会话的活动交易。如果会话中没有活动交易或交易已被提交或结束,则返回错误。有关此方法的更多信息,请参阅服务器手册中的abortTransaction()页面。 参数: Context 返回类型: error |
CommitTransaction() | 提交此会话的活动交易。如果会话中没有活动交易或交易已被结束,则返回错误。有关此方法的更多信息,请参阅服务器手册中的commitTransaction()页面。 CommitTransaction() 方法是一个幂等函数,这意味着您可以在第一次成功提交后多次尝试提交交易而不会更改数据。一个交易可以成功但返回带有UnknownTransactionCommitResult 标签的错误。如果您在此错误后重新运行CommitTransaction() 方法,重复尝试不会更改数据。参数: Context 返回类型: error |
WithTransaction() | 在此会话上启动交易并运行 fn 回调。参数: Context ,fn func(ctx SessionContext) ,TransactionOptions 返回类型: interface{} ,error |
EndSession() | 结束任何现有交易并关闭会话。 参数: Context 返回类型: 无 |
Session
接口还具有检索会话属性和修改可变会话属性的方法。更多信息请参阅API文档。
示例
以下示例展示了如何通过以下步骤创建会话、创建事务并提交多文档插入操作:
使用
StartSession()
方法从客户端创建会话。使用
WithTransaction()
方法开始事务。插入多个文档。在
WithTransaction()
方法中执行插入并提交事务。如果任何操作导致错误,WithTransaction()
将处理取消事务。使用
EndSession()
方法关闭事务和会话。
wc := writeconcern.Majority() txnOptions := options.Transaction().SetWriteConcern(wc) // Starts a session on the client session, err := client.StartSession() if err != nil { panic(err) } // Defers ending the session after the transaction is committed or ended defer session.EndSession(context.TODO()) // Inserts multiple documents into a collection within a transaction, // then commits or ends the transaction result, err := session.WithTransaction(context.TODO(), func(ctx mongo.SessionContext) (interface{}, error) { result, err := coll.InsertMany(ctx, []interface{}{ bson.D{{"title", "The Bluest Eye"}, {"author", "Toni Morrison"}}, bson.D{{"title", "Sula"}, {"author", "Toni Morrison"}}, bson.D{{"title", "Song of Solomon"}, {"author", "Toni Morrison"}}, }) return result, err }, txnOptions)
如果您需要更多对事务的控制,可以查看如何手动创建、提交和结束事务的完整代码示例。
更多信息
有关插入操作的更多信息,请参阅插入文档 基础页面。
有关在 Go 驱动程序中指定写入关注点的更多信息,请参阅 写入关注点。
关于使用Go驱动程序进行会话和事务的附加示例,请参阅关于多文档ACID事务的开发者博客文章。
API文档
要了解更多关于本指南中讨论的任何类型或方法的信息,请参阅以下API文档