19

I am new to MongoDB. I read that MongoDB does not support multi-document transactionshere http://docs.mongodb.org/manual/faq/fundamentals/.

If I want to save data in two collections(A and B) atomically, then i can't do that using MongoDB i.e. if save fails in case of B, still A will have the data. Isn't it a big disadvantage?

Still, people are using MongoDB rather than RDBMS. Why?

Community
  • 1
  • 1
Anand
  • 20,708
  • 48
  • 131
  • 198
  • 2
    Apart from being way too broad and subjective, the default answer: because we want to and it fits our scenario? Also think about it: in a non-money/resource transaction app (like 90% of apps out there) how many rows truly rely on each other? Instead you can implement something known as eventual consistentcy for this, whereby it makes it on-demand in pieces. That is, of course, much faster and easier to scale as well – Sammaye Nov 20 '14 at 11:28
  • @Sammaye rightly said. Its all about your use case. NoSQL is more used for storing raw data which grows huge and getting business value from it. Coming to transaction support it doesn't support it. you might like this not sure if its out in market for use http://www.tokutek.com/2013/04/mongodb-multi-statement-transactions-yes-we-can/ – Ninad Nov 20 '14 at 12:02

8 Answers8

15

MongoDB 4.0 adds support for multi-document ACID transactions now. For reference See Refrence

Mithilesh Jha
  • 175
  • 1
  • 11
10

UPDATE MongoDB have already started to support multi-document transactions. https://docs.mongodb.com/manual/core/transactions/

MongoDB does not support multi-document transactions.

However, MongoDB does provide atomic operations on a single document. Often these document-level atomic operations are sufficient to solve problems that would require ACID transactions in a relational database.

For example, in MongoDB, you can embed related data in nested arrays or nested documents within a single document and update the entire document in a single atomic operation. Relational databases might represent the same kind of data with multiple tables and rows, which would require transaction support to update the data atomically.

Isabel Jinson
  • 8,541
  • 16
  • 59
  • 75
3

MongoDB doesn't support transactions, but saving one document is atomic.

So, it is better to design you database schema in such a way, that all the data needed to be saved atomically will be placed in one document.

stalk
  • 11,934
  • 4
  • 36
  • 58
  • 1
    If you have two bank accounts that need to transfer money it would not be good practice to save both of those accounts in one document, or, if you allow transactions between all accounts, all of them in one document – Sammaye Nov 20 '14 at 11:45
  • @Sammaye I can provide a bitcoin approach as an example. So, one person need to transfer some of his balance to other person. Only one document will be created in that case - a `transaction` (it just the name of collection, it is not a transaction in terms of SQL). Account don't have field with his balance, the balance is always counted according to list of transactions. – stalk Nov 20 '14 at 12:08
  • So you would have a transaction that is read by both bank accounts? That sounds very...insecure, using the transactions as a count for balance is bad enough – Sammaye Nov 20 '14 at 12:17
  • @Sammaye why it is insecure? You operate with transactions on your server. If transaction involves some account, then this account must process this transaction. I think it secure enough. – stalk Nov 20 '14 at 12:20
  • You are judging one persons account balance based upon anothers. I wouldnt like my bank balance to be betted on the balance transactions of those who I have transferred to. Also transactions may not always represent the balance, you can have extra-transactional money withdrawals – Sammaye Nov 20 '14 at 12:24
  • @Sammaye Account balance is always counted according to transactions this account involved in. It doesn't read other balances. Are you familiar with bitcoin? – stalk Nov 20 '14 at 12:28
  • I am not but I am familiar with the software used in Banks. I do not use bitcoin, kind of glad hearing that. It does read other balances, a transaction between two accounts is being used in both accounts to calculate the balance of both, there is cross over – Sammaye Nov 20 '14 at 12:35
3

MongoDB does not support transactions as in Relational DB. ACID postulates in transactions is a complete different functionality provided by storage engines in MySQL

Some of the features of InnoDB engine in MySQL:

  • Crash Recovery
  • Double write buffer
  • Auto commit settings
  • Isolation Level

This is what MongoDB community has to say:

MongoDB does not have support for traditional locking or complex transactions with rollback.

MongoDB aims to be lightweight, fast, and predictable in its performance. By keeping transaction support extremely simple, MongoDB can provide greater performance especially for partitioned or replicated systems with a number of database server processes.

The purpose of a transaction is to make sure that the whole database stays consistent while multiple operations take place.

But in contrary to most relational databases, MongoDB isn't designed to run on a single host. It is designed to be set up as a cluster of multiple shards where each shard is a replica-sets of multiple servers (optionally at different geographical locations).

But if you are still looking for way to make transactions possible:

  • Try using document level atomicity provided by mongo
  • two phase commit in Mongo provides simple transaction mechanism for basic operations
  • mongomvcc is built on the top of mongo and also supports transaction as they say
  • Hybrid of MySQL and Mongo
keshav
  • 734
  • 6
  • 19
1

Multi-document updates or “multi-document transactions” using a two-phase commit approac described here: http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/

Rahatur
  • 3,147
  • 3
  • 33
  • 49
1

This question is quite old but for anyone who stumbles upon this page, you could use fawn. It's an npm package that solves this exact problem. Disclosure: I wrote it

Say you have two bank accounts, one belongs to John Smith and the other belongs to Broke Individual. You would like to transfer $20 from John Smith to Broke Individual. Assuming all first name and last name pairs are unique, this might look like:

var Fawn = require("fawn");
var task = Fawn.Task()

//assuming "Accounts" is the Accounts collection 
task.update("Accounts", {firstName: "John", lastName: "Smith"}, {$inc: {balance: -20}})
  .update("Accounts", {firstName: "Broke", lastName: "Individual"}, {$inc: {balance: 20}})
  .run()
  .then(function(){
    //update is complete 
  })
  .catch(function(err){
    // Everything has been rolled back. 

    //log the error which caused the failure 
    console.log(err);
  });

Caveat: tasks are currently not isolated(working on that) so, technically, it's possible for two tasks to retrieve and edit the same document just because that's how MongoDB works.

It's really just a generic implementation of the two phase commit example on the tutorial site: https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits/

e-oj
  • 209
  • 2
  • 5
  • 2
    While you _have_ disclosed your affiliation with the links, making it not spam, it is still a __link-only answer__, which are typically deleted. It's better to summarize the key points in the answer, and provide the link for reference. – Nissa Nov 10 '16 at 22:54
  • @JohnnyHK I've added that info – e-oj Nov 12 '16 at 14:07
0

Starting from version 4.0 MongoDB will add support for multi-document transactions. So you will have the power of the document model with ACID guarantees in MongoDB. Transactions in MongoDB will be like transactions in relational databases.

For details visit this link: https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb?jmp=community

Pranab Sharma
  • 729
  • 10
  • 12
-1

Only support Single Document Transaction.

You can see it at: https://docs.mongodb.com/v3.2/tutorial/perform-two-phase-commits/

ThienSuBS
  • 1,574
  • 18
  • 26