-
Type:
Improvement
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: 3.6.0
-
Component/s: None
-
None
-
None
-
None
-
None
-
None
-
None
-
None
-
None
I am following the example in https://docs.mongodb.com/manual/core/transactions/ with a deployment using 4.0 replica set with mmapv1 which does not support transactions.
const { MongoClient } = require("mongodb"); const uri = "mongodb://localhost:14071/?retrywrites=false&directconnection=false" const client = new MongoClient(uri,{useUnifiedTopology:true}); async function run() { await client.connect(); // Prereq: Create collections. await client.db('mydb1').collection('foo').insertOne({ abc: 0 }, { w: 'majority' }); await client.db('mydb2').collection('bar').insertOne({ xyz: 0 }, { w: 'majority' }); // Step 1: Start a Client Session const session = client.startSession(); // Step 2: Optional. Define options to use for the transaction const transactionOptions = { readPreference: 'primary', readConcern: { level: 'local' }, writeConcern: { w: 'majority' } }; // Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error) // Note: The callback for withTransaction MUST be async and/or return a Promise. try { await session.withTransaction(async () => { const coll1 = client.db('mydb1').collection('foo'); const coll2 = client.db('mydb2').collection('bar'); // Important:: You must pass the session to the operations await coll1.insertOne({ abc: 1 }, { session }); await coll2.insertOne({ xyz: 999 }, { session }); }, transactionOptions); } finally { await session.endSession(); await client.close(); } } run().catch(console.dir);
I get the following diagnostics:
serene% node test.js MongoError: This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string. at getMMAPError (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/core/topologies/shared.js:413:18) at handler (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/core/sdam/topology.js:944:15) at /home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/cmap/connection_pool.js:354:13 at handleOperationResult (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/core/sdam/server.js:558:5) at commandResponseHandler (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/core/wireprotocol/command.js:115:25) at MessageStream.messageHandler (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/cmap/connection.js:266:11) at MessageStream.emit (events.js:315:20) at processIncomingData (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/cmap/message_stream.js:144:12) at MessageStream._write (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/cmap/message_stream.js:42:5) at doWrite (_stream_writable.js:403:12) { originalError: MongoError: Transaction numbers are only allowed on storage engines that support document-level locking at MessageStream.messageHandler (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/cmap/connection.js:266:20) at MessageStream.emit (events.js:315:20) at processIncomingData (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/cmap/message_stream.js:144:12) at MessageStream._write (/home/w/apps/tests/retryable-writes-node/node_modules/mongodb/lib/cmap/message_stream.js:42:5) at doWrite (_stream_writable.js:403:12) at writeOrBuffer (_stream_writable.js:387:5) at MessageStream.Writable.write (_stream_writable.js:318:11) at Socket.ondata (_stream_readable.js:717:22) at Socket.emit (events.js:315:20) at addChunk (_stream_readable.js:295:12) { operationTime: Timestamp { _bsontype: 'Timestamp', low_: 2, high_: 1596646405 }, ok: 0, code: 20, codeName: 'IllegalOperation', '$clusterTime': { clusterTime: [Timestamp], signature: [Object] } } }
Note that the error message instructs me to add retrywrites=false to the connection string, which I have already done. This is a very confusing situation to deal with as a user of the driver.
The Ruby driver provides the "Please add retryWrites=false to your connection string." instruction when issuing inserts and retrywrites=false is not set (in which case setting retrywrites=false would in fact fix the insert not working), but not when issuing transactions where it doesn't help.
I expect the node driver to:
- Not suggest to users that they add retrywrites=false to their connection string when this option is already requested by the users.
- Not suggest to users that they add retrywrites=false when this will not make the operation succeed, specifically when they are attempting transactions.
Test code:
https://github.com/p-mongo/tests/tree/master/retryable-writes-node
https://github.com/p-mongo/tests/tree/master/retryable-writes-ruby