writeConcern is not allowed within a multi-statement transaction

We recently upgraded to Mongo 4.4 and are running into issues with transactions. On 4.0 and 4.2, this following PyMongo code works:

from pymongo import MongoClient,WriteConcern
client = MongoClient("url")
client.t.t.insert_one({}) # Create collection
with client.start_session() as s, s.start_transaction():
    client.t.t.insert_one({}, session=s)

As of 4.4, it always fails with the titular error. It’s not a PyMongo issue, as even creating a transaction via the shell causes the same error to happen. We’re baffled as to what configuration issue could be causing this. All of our servers are on 4.4.4 (one primary and two secondaries in a replica set), and the compatibility value is 4.4. Any advice?

I cannot reproduce this error with the info you’ve provided. The code example works as expected on 4.4.4 for me:

>>> client = MongoClient(w='majority')
>>> client.t.t.insert_one({}) # Create collection
<pymongo.results.InsertOneResult object at 0x7fe853a3ee00>
>>> with client.start_session() as s, s.start_transaction():
...     client.t.t.insert_one({}, session=s)
...
<pymongo.results.InsertOneResult object at 0x7fe85668e6c0>

Could you please provide the full python, pymongo, and server version info? Like this:

>>> import sys
>>> sys.version
'3.9.0 (v3.9.0:9cf6752276, Oct  5 2020, 11:29:23) \n[Clang 6.0 (clang-600.0.57)]'
>>> import pymongo
>>> pymongo.version
'3.11.3'
>>> client.server_info()
{'version': '4.4.4', 'gitVersion': '8db30a63db1a9d84bdcad0c83369623f708e0397', 'modules': ['enterprise'], 'allocator': 'system', 'javascriptEngine': 'mozjs', 'sysInfo': 'deprecated', 'versionArray': [4, 4, 4, 0], 'openssl': {'running': 'Apple Secure Transport'}, ..., 'bits': 64, 'debug': False, 'maxBsonObjectSize': 16777216, 'storageEngines': ['biggie', 'devnull', 'ephemeralForTest', 'inMemory', 'queryable_wt', 'wiredTiger'], 'ok': 1.0, '$clusterTime': {'clusterTime': Timestamp(1614705437, 1), 'signature': {'hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'keyId': 0}}, 'operationTime': Timestamp(1614705437, 1)}

Please also include the full exception traceback. For example, I can force the server to return this error (mis)using the low-level Database.command API like this:

>>> with client.start_session() as s, s.start_transaction():
...     client.t.command('insert', 't', documents=[{}], writeConcern={'w':1}, session=s)
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/Users/shane/git/mongo-python-driver/pymongo/database.py", line 738, in command
    return self._command(sock_info, command, slave_ok, value,
  File "/Users/shane/git/mongo-python-driver/pymongo/database.py", line 626, in _command
    return sock_info.command(
  File "/Users/shane/git/mongo-python-driver/pymongo/pool.py", line 683, in command
    return command(self, dbname, spec, slave_ok,
  File "/Users/shane/git/mongo-python-driver/pymongo/network.py", line 159, in command
    helpers._check_command_response(
  File "/Users/shane/git/mongo-python-driver/pymongo/helpers.py", line 164, in _check_command_response
    raise OperationFailure(errmsg, code, response, max_wire_version)
pymongo.errors.OperationFailure: writeConcern is not allowed within a multi-statement transaction, full error: {'operationTime': Timestamp(1614706228, 1), 'ok': 0.0, 'errmsg': 'writeConcern is not allowed within a multi-statement transaction', 'code': 72, 'codeName': 'InvalidOptions', '$clusterTime': {'clusterTime': Timestamp(1614706228, 1), 'signature': {'hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'keyId': 0}}}

The issue apparently was that our replica set had this configuration:

"chainingAllowed" : true,
		"heartbeatIntervalMillis" : 2000,
		"heartbeatTimeoutSecs" : 10,
		"electionTimeoutMillis" : 10000,
		"catchUpTimeoutMillis" : 60000,
		"catchUpTakeoverDelayMillis" : 30000,
		"getLastErrorModes" : {
		},
		"getLastErrorDefaults" : {
			"w" : 1,
			"j" : false,
			"wtimeout" : 5000
		}

When updated to:

"settings" : {
		"chainingAllowed" : true,
		"heartbeatIntervalMillis" : 2000,
		"heartbeatTimeoutSecs" : 10,
		"electionTimeoutMillis" : 10000,
		"catchUpTimeoutMillis" : -1,
		"catchUpTakeoverDelayMillis" : 30000,
		"getLastErrorModes" : {
		},
		"getLastErrorDefaults" : {
			"w" : 1,
			"wtimeout" : 0
		},
		"replicaSetId" : ObjectId("5773018ecc19f9e600e06b22")
	}

note getLastErrorDefaults and catchUpTimeoutMillis

Transactions began working again. Why that caused it, I don’t know.

Thanks for reporting this. I’ve filed this as a bug in the server: https://jira.mongodb.org/browse/SERVER-54896

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.