【问题标题】:what does the function incrementTransactionNumber() do in mongodb node driver?mongodb 节点驱动程序中的函数 incrementTransactionNumber() 有什么作用?
【发布时间】:2021-03-18 17:14:29
【问题描述】:

我知道函数的名称似乎是不言自明的,但是,在研究了很长一段时间后,我在 clientSession 中的任何地方都找不到事务号。 是内部号码吗?有可能得到吗?

【问题讨论】:

    标签: node.js mongodb apollo-datasource


    【解决方案1】:

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

    incrementTransactionNumber() 如何处理会话(显式)

    当您启动会话时,通过调用client.startSession() method,它将创建一个新的ClientSession。这会将已创建的服务器会话池作为其构造函数参数之一。 (See) 这些服务器会话有一个名为 txnNumber 的属性,它被初始化为 0。(Init) 因此,每当您通过调用 startTransaction() 启动事务时,客户端会话对象都会在内部调用 incrementTransactionNumber() 以增加 txnNumber in服务器会话。并且所有后续操作都将使用相同的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;
      }
    

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

    incrementTransactionNumber() 如何处理会话(隐式)

    在这种情况下,如果该命令不属于事务并且它是启用了 retryWrites 的写入操作,则每次向数据库发出新命令时都会调用它。因此,只要每个新的写操作不属于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 获取任何会话的事务编号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-18
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多