mongodb 节点驱动程序中的函数 incrementTransactionNumber() 做什么?

what does the function incrementTransactionNumber() do in mongodb node driver?

我知道该函数的名称似乎是不言自明的,但是,经过一段时间的研究后,我无法在 clientSession 中的任何地方找到交易号。 是内部号码吗?有可能拿到吗?

mongodb 使用交易编号来跟踪每个会话每个交易的操作 (read/writes)。会话可以通过调用 startSession() 显式启动,也可以在您创建与数据库服务器的 mongodb 连接时隐式启动。

incrementTransactionNumber() 如何与会话一起工作(显式)

当您通过调用 client.startSession() method, it will create a new ClientSession. This takes in already created server session pool as one of its' constructor parameters. (See) These server sessions have a property called txnNumber which is initialized to be 0.(Init) 启动一个会话时,因此每当您通过调用 startTransaction() 启动一个事务时,客户端会话对象会在内部调用 incrementTransactionNumber() 来递增txnNumber 在服务器会话中。并且所有后续操作将使用相同的 txnNumber,直到您调用 commitTransaction()abortTransaction() 方法。在 clientSession 中找不到它的原因是,它是 serverSession 的 属性 而不是 clientSession。

ServerSession

class ServerSession {
  constructor() {
    this.id = { id: new Binary(uuidV4(), Binary.SUBTYPE_UUID) };
    this.lastUse = now();
    this.txnNumber = 0;
    this.isDirty = false;
  }

因此,每当您尝试向数据库 (read/write) 发送命令时,此 txnNumber 将与其一起发送。 (Assign transaction number to command) 这是为了跟踪属于每个会话的给定事务的数据库操作。 (唯一标识每个会话的每个交易的交易操作历史。)

incrementTransactionNumber() 如何与会话一起工作(隐式)

在这种情况下,如果该命令不属于事务并且是启用了重试写入的写操作,则每次向数据库发出新命令时都会调用它。所以每个新的写操作都会有新的事务编号,只要它不属于 startTransaction() 的显式启动事务。但在这种情况下,txnNumber 也会随每个命令一起发送。

execute_operation.

const willRetryWrite =
      topology.s.options.retryWrites === true &&
      session &&
      !inTransaction &&
      supportsRetryableWrites(server) &&
      operation.canRetryWrite;

    if (
      operation.hasAspect(Aspect.RETRYABLE) &&
      ((operation.hasAspect(Aspect.READ_OPERATION) && willRetryRead) ||
        (operation.hasAspect(Aspect.WRITE_OPERATION) && willRetryWrite))
    ) {
      if (operation.hasAspect(Aspect.WRITE_OPERATION) && willRetryWrite) {
        operation.options.willRetryWrite = true;
        session.incrementTransactionNumber();
      }

      operation.execute(server, callbackWithRetry);
      return;
    }

    operation.execute(server, callback);

也请阅读 this article。是的,如果您需要,您可以通过 txnNumber 属性、clientSession.serverSession.txnNumber.

获取任何会话的交易编号