MongoDB Atlas Error while performing transaction o

2019-04-09 11:09发布

问题:

I'm trying to perform a transaction on a Mongo DB Atlas M0 instance from Mongo DB Node JS driver (as described here) and I'm getting the following error:

code:8000
codeName:"AtlasError"
errmsg:"internal atlas error checking things: Failure getting dbStats: read tcp 192.168.254.78:50064->192.168.254.78:27000: i/o timeout"
message:"internal atlas error checking things: Failure getting dbStats: read tcp 192.168.254.78:50064->192.168.254.78:27000: i/o timeout"
name:"MongoError"

I've been searching for a while now and can't find any clue on how to solve this.

Aditional information:

  • The error is thrown after adding the second operation to the transaction.

  • If I remove all the other operations and leave only one (doesn't
    matter which) it works fine.

  • If I change the order of the operations (to any order) the error is
    still on adding the second operation.

  • If the operations are all performed to the same db and collection, it works fine

My code:

async function connect () {

if (dbClient !== null && dbClient.isConnected()) {
    console.log('Reusing db connection => ' + JSON.stringify(dbClient));
  } else {
      console.log('Connecting to database');
      dbClient = await MongoClient.connect(url, { useNewUrlParser: true });
      console.log('Successfully connected to database');
  }
}

async function insertDocuments(document1, document2, document3) {

  try {
    await connect();
  } catch (error) {
    throw error
  }

  let session = dbClient.startSession();

  session.startTransaction({
    readConcern: { level: 'snapshot' },
    writeConcern: { w: 'majority' }
  });

  const collection1 = dbClient.db('mydbname').collection('collection1');
  const collection2 = dbClient.db('mydbname').collection('collection2');
  const collection3 = dbClient.db('mydbname').collection('collection3');
  const logsCollection = dbClient.db('mydbname').collection('logs');

  await collection1.replaceOne(
    { _id: document1._id },
    document1,
    {
      upsert: true,
      session
    }
  );
  await collection2.replaceOne(
    { _id: document2._id },
    document2,
    {
      upsert: true,
      session
    }
  );
  await collection3.replaceOne(
    { _id: document3._id },
    document3,
    {
      upsert: true,
      session
    }
  );
  await logsCollection.updateOne(
    { _id: document1._id },
    { $unset: { estoque: '' } },
    { session }
  );

  try {
    await commitWithRetry(session);
  } catch (error) {
    await session.abortTransaction();
    throw error;
  }
}

async function commitWithRetry(session) {
  try {
    await session.commitTransaction();
    console.log('Transação gravada com sucesso');
  } catch (error) {
    if (
      error.errorLabels &&
      error.errorLabels.indexOf('UnknownTransactionCommitResult') >= 0
    ) {
      console.log('Transação não realizada, tentando novamente ...');
      await commitWithRetry(session);
    } else {
      console.log('Erro ao gravar no banco de dados ...');
      throw error;
    }
  }
}

Any idea on how to fix this? Thanks in advance!

回答1:

I had this same issue and could not solve it. I ended up creating a new cluster on Azure (instead of AWS) and it seems to be working fine.

Not sure if this is an issue with their implementation on AWS or case by case mis-configuration

Update: The same error is now happening on the new cluster. I raised a ticket and got the following response;

This has been determined to be a bug currently affecting the M0 free cluster and shared tiers of Atlas (M2 and M5). We have opened an internal bug report to address this. While the internal development queue for our Cloud products is not publicly visible, we are tracking the work required to make multi-document transactions work on Atlas free tier clusters.

They said the same thing as the other answer. Please use M10. However, M10 is about $60/m which is not quite a resolution by any means. It also completely invalidates the main selling point of them saying M0 now includes MongoDb 4.0



回答2:

As mentioned in comments, according to MongoDB team this issue has been solved on version 4.0.5

I've tested the same code posted on my question and it now works fine.

For anyone facing the same issue, make sure to be using a version equal to or higher than 4.0.5.



回答3:

I was having the same issue. Support was not specially helpful as they said that since I was using Mongoose they couldn't help me out. However, they were kind enough to gift me 10$ in credit so I could test it out with a higher tier.

That was the issue, as soon as I upgraded to M10 tier (the next one after M0) transactions started working as intended. Your code is very similar as mine, only that I was creating one document and updating 2 others at the same time. Just like in your case, the first one went through (no matter the order) and the next just timed out with the same error.

Hope it helps :)