Parameter max Transaction Lock Request Timeout Millis is not working

According to https://docs.mongodb.com/manual/reference/parameters/#mongodb-parameter-param.maxTransactionLockRequestTimeoutMillis this parameter should cause competing transaction to wait on the lock, not to fail.
I set maxTransactionLockRequestTimeoutMillis to 3 seconds in mongod.conf:
setParameter:
maxTransactionLockRequestTimeoutMillis: 3000

And after restarting mongod I can get this value in mongo shell (i.e. it is set), but I do not see its effect:

  • In one mongo shell window I start transaction and update one document by ID (it should lock this document)
  • In second mongo shell window I execute similar code: start transaction and try to update the same document. Update operation fails immediately with “write conflict” instead of waiting for 3 seconds.

It looks like this parameter is not working as described in the docs.

Environment: local mongodb 5.0 on Windows, single node replicaset.

More info on how to reproduce:

Environment: Windows, mongodb 5.0, single node replicaset.

in mongod.cfg

setParameter:
  maxTransactionLockRequestTimeoutMillis: 3000

Create DB and collection test with one object:

objId = ObjectId("613233675a5ea6722c960051");
db.test.insert({_id: objId, item: "A"});

Open 2 mongo shell windows to create 2 concurrent transactions: Window 1:

   session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
   coll = session.getDatabase(dbName).getCollection("test");
   session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } );
   coll.updateOne({_id: objId}, { $set: {item: "B"}})

Window 2:

session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
coll = session.getDatabase(dbName).getCollection("test");
session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } );
coll.updateOne({_id: objId}, { $set: {item: "C"}})

Second update fails immediately without waiting for 3 seconds:

WriteCommandError({
        "errorLabels" : [
                "TransientTransactionError"
        ],
        "ok" : 0,
        "errmsg" : "WriteConflict error: this operation conflicted with another operation. Please retry your operation or multi-document transaction.",
        "code" : 112,
        "codeName" : "WriteConflict",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1632429457, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1632429457, 1)
})

I got reply on stackoverflow that this is not how maxTransactionLockRequestTimeoutMillis supposed to work. Then the question remains: how is it supposed to work? Anybody can provide an example? Preferably in mongo shell, as this is the simplest to reproduce. I saw unit test in mongodb code testing this param, but the test seems to create lock directly, not through execution of an operation on data.

1 Like

Hi,

I want to know how to add maxTransactionLockRequestTimeoutMillis by Mongo Ops Manager when startup replica also by Mongo Ops Manager ?

The Modify config in Mongo Ops Manager does not have the maxTransactionLockRequestTimeoutMillis parameter.

I try to add these line to the file config of automation Mongo Ops Manager in each node in replica:

setParameter:
maxTransactionLockRequestTimeoutMillis: 3000

But it will disappear after restart instance by Mongo Ops Manager