在阅读了许多关于MongoDB事务的文档/文章后,我仍然需要进一步澄清.

Here上面写着:

MongoDB提供了两个使用事务的API.第一个是核心API,它的语法类似于关系数据库.第二个是回调API,它是在MongoDB中使用事务的recommended方法.

然而,它继续引入了核心API方法,完全没有触及推荐的方法.

官方文件here说,

此示例重点介绍了Transaction API的关键组件.特别是,它使用了回调API.回调接口:

  • 启动一项交易
  • 执行指定的操作
  • 提交结果(或在出错时中止)

然而,当涉及到最重要的"执行指定的操作"步时,该示例没有显示任何相关代码.也就是说,正如在MongoDB Transactions In NodeJS,"still need a real example"中所要求的那样.

PS.如果示例被更改或消失,这里是Golang版本:

// WithTransactionExample is an example of using the Session.WithTransaction function.
func WithTransactionExample(ctx context.Context) error {
    // For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g.
    // uri := "mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl"
    // For a sharded cluster, connect to the mongos instances; e.g.
    // uri := "mongodb://mongos0.example.com:27017,mongos1.example.com:27017/"
    uri := mtest.ClusterURI()
    clientOpts := options.Client().ApplyURI(uri)
    client, err := mongo.Connect(ctx, clientOpts)
    if err != nil {
        return err
    }
    defer func() { _ = client.Disconnect(ctx) }()
    // Prereq: Create collections.
    wcMajority := writeconcern.Majority()
    wcMajority.WTimeout = 1 * time.Second
    wcMajorityCollectionOpts := options.Collection().SetWriteConcern(wcMajority)
    fooColl := client.Database("mydb1").Collection("foo", wcMajorityCollectionOpts)
    barColl := client.Database("mydb1").Collection("bar", wcMajorityCollectionOpts)
    // Step 1: Define the callback that specifies the sequence of operations to perform inside the transaction.
    callback := func(sessCtx mongo.SessionContext) (interface{}, error) {
        // Important: You must pass sessCtx as the Context parameter to the operations for them to be executed in the
        // transaction.
        if _, err := fooColl.InsertOne(sessCtx, bson.D{{"abc", 1}}); err != nil {
            return nil, err
        }
        if _, err := barColl.InsertOne(sessCtx, bson.D{{"xyz", 999}}); err != nil {
            return nil, err
        }
        return nil, nil
    }
    // Step 2: Start a session and run the callback using WithTransaction.
    session, err := client.StartSession()
    if err != nil {
        return err
    }
    defer session.EndSession(ctx)
    result, err := session.WithTransaction(ctx, callback)
    if err != nil {
        return err
    }
    log.Printf("result: %v\n", result)
    return nil
}

在我看来,从这个例子来看,最重要的"执行指定的操作"步是在回调中完成的.是真地吗?如果是这样的话,官方文件真的需要强调这一点.

推荐答案

这个例子已经完成了.它包含这样的关键注释:

// Step 2: Start a session and run the callback using WithTransaction.

因此,callback函数由Session.WithTransaction()执行 方法.您将callback函数传递给它,它将被Session.WithTransaction()方法调用.

该实现确保在回调函数中完成的操作将作为事务执行(即,要么全部应用,要么全部不应用).如果回调函数返回非nil错误,则事务将中止,否则将提交事务.

Database相关问答推荐

无法连接MatrixOne(来自GitHub)

从仅连接器电源查询制作图表

SQL 查询至少其中一项

MySQL 慢查询日志(log) - 慢有多慢?

更新查询 PHP MySQL

Java中基于文件的数据库

su postgres:Sorry?

SQLite3 的动态类型

在 MS SQL 中使用 GUID 作为主键是不是一个坏主意?

如何从 MySQL 行中修剪前导和尾随引号?

返回 SQLite 数据库中表大小的查询

使用 typeORM 搜索早于日期的数据

归档实时 MySQL 数据库的最佳方式

在 MySQL 存储过程中使用if和else

Oracle 的免费桌面客户端?

从 CSV 文件填充 Android 数据库?

PostgreSQL 的示例数据库

用 SQL 进行条件插入?

遍历数据库中的每条记录 - Ruby on Rails / ActiveRecord

是否有用于 postgresql 的数据可视化工具,它也能够显示模式间关系?