4

I have a scenario where an API call needs to update two separate collections. If one update fails I need to revert back the first update. How do I ensure that either both the operations complete successfully or none. To help clarify, here's the situation. Using MongoJS in express framework.

Question Model

{
    _id: ObjectId(),
    title: String,
    description: String,
    accepted: String,
    // Some other fields
}

Answer Model

{
    _id: ObjectId(),
    qid: String, //ObjectId of question its linked to
    body: String,
    accepted: boolean,
    // Some other fields
}

Approach 1: First pull the answer corresponding to the id sent in request. Mark it as accepted and get the qid. Insert the answer id in the question document corresponding to qid. If second operation fails, revert back first operation. But if db connection is lost, it cannot be performed.

Approach 2 First get the question corresponding to qid. Update the accepted field with answer id and then get the answer corresponding to it and mark it as accepted.

Then there is the case that if one answer is accepted, we need to make all other answers as not accepted. that's a third operation. Furthermore, its a toggle operation, so if it was already accepted, we need to do the reverse.

I have a feeling there's a cleaner and safer way to handle this situation.

Nil
  • 401
  • 1
  • 6
  • 18
  • I have a similar requirement. Did you find a solution? – Jag99 Aug 11 '21 at 04:57
  • From comment by @Robb Sadler: > As of version 4, transaction updates are possible: docs.mongodb.com/manual/core/transactions – – Nil Aug 16 '21 at 07:05

1 Answers1

1

MongoDB does not have a way of doing multi-document transactions. So there's no clean way of doing roll-backs like this. It must be implemented in the application. The MongoDB documentation suggests using a two-phase commit pattern to make transaction-like semantics. You can implement roll-backs using this, but this can be quite cumbersome.

An alternative is rethinking your document schema. Can you embed your answer documents in your question documents? Using embedded documents would be a better use of Mongo's capabilities rather than trying to implement transactions. MongoDB has atomic writes for single documents, so if there is an error updating an embedded document your whole operation can be rolled back.

tfogo
  • 1,416
  • 1
  • 14
  • 23
  • Embedding will have problems. it will be an arrray of answers which subsequently will have an array of replies. Performing updates on replies will become impossible then. – Nil Sep 24 '17 at 09:42
  • Hmm... will you want to update the replies and the answers/questions at the same time like with the answers and questions? If not, maybe having the replies in a separate collection and just having an array of reply `_id`s in the answer may work? – tfogo Sep 24 '17 at 09:50
  • 1
    As of version 4, transaction updates are possible: https://docs.mongodb.com/manual/core/transactions/ – Robb Sadler Oct 09 '18 at 12:20