0

I know the function's name seems to be self explanatory, however, after researching for quite a while I can't find a transaction number anywhere within a clientSession. Is it an internal number ? is it possible to get it ?

asma
  • 11
  • 3

1 Answers1

0

Transaction numbers are used by mongodb to keep track of operations(read/writes) per transaction per session. Sessions can be started either explicitly by calling startSession() or implicity whenever you create a mongodb connection to db server.

How incrementTransactionNumber() works with sessions (explicit)

When you start a session, by calling 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) So whenever you start a transaction by calling startTransaction(), client session object calls incrementTransactionNumber() internally to increment the txnNumber in server session. And all the successive operations will use the same txnNumber, until you call, commitTransaction() or abortTransaction() methods. Reason that you can't find it anywhere within clientSession is, it is a property of serverSession not clientSession.

ServerSession

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

So whenever you try to send a command to database (read/write), this txnNumber would be sent along with it. (Assign transaction number to command) This is to keep track of database operations that belong to a given transaction per session. (A transaction operation history that uniquely identify each transaction per session.)

How incrementTransactionNumber() works with sessions (implicit)

In this case it would be called every time a new command is issued to the database if that command does not belong to a transaction and it's a write operation where retryWrites are enabled. So each new write operation would have new transaction number as long as it does not belong to a explicitly started transaction with startTransaction(). But in this case as well a txnNumber would be sent along with each command.

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);

Also read this article as well. And yes if you need you can get the transaction number for any session through txnNumber property, clientSession.serverSession.txnNumber.

v1shva
  • 1,261
  • 3
  • 13
  • 28