Multi-collection, multi-document 'transactions' in MongoDB

前端 未结 3 403
悲&欢浪女
悲&欢浪女 2020-12-25 14:47

I realise that MongoDB, by it\'s very nature, doesn\'t and probably never will support these kinds of transactions. However, I have found that I do need to use them in a so

相关标签:
3条回答
  • 2020-12-25 14:59

    MongoDB 4.0 adds support for multi-document ACID transactions.

    Java Example:

    try (ClientSession clientSession = client.startSession()) {
       clientSession.startTransaction();
       collection.insertOne(clientSession, docOne);
       collection.insertOne(clientSession, docTwo);
       clientSession.commitTransaction();
    }
    

    Note, it works for replica set. You can still have a replica set with one node and run it on local machine.

    • https://stackoverflow.com/a/51396785/4587961
    • https://docs.mongodb.com/manual/tutorial/deploy-replica-set-for-testing/
    0 讨论(0)
  • 2020-12-25 15:11

    As a generic response multi-document commits on MongoDB can be performed as two phase commits, which have been somewhat extensively documented in the manual (See: http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/).

    The pattern suggested by the manual is briefly to following:

    • Set up a separate transactions collection, that includes target document, source document, value and state (of the transaction)
    • Create new transaction object with initial as the state
    • Start making a transaction and update state to pending
    • Apply transactions to both documents (target, source)
    • Update transaction state to committed
    • Use find to determine whether documents reflect the transaction state, if ok, update transaction state to done

    In addition:

    • You need to manually handle failure scenarios (something didn't happen as described below)
    • You need to manually implement a rollback, basically by introducing a name state value canceling

    Some specific notes for your implementation:

    • I would discourage you from adding fields like lock_status, data_old, data_new into source/target documents. These should be properties of the transactions, not the documents themselves.
    • To generalize the concept of target/source documents, I think you could use DBrefs: http://www.mongodb.org/display/DOCS/Database+References
    • I don't like the idea of deleting transaction documents when they are done. Setting state to done seems like a better idea since this allows you to later debug and find out what kind of transactions have been performed. I'm pretty sure you won't run out of disk space either (and for this there are solutions as well).
    • In your model how do you guarantee that everything has been changed as expected? Do you inspect the changes somehow?
    0 讨论(0)
  • 2020-12-25 15:26

    MongoDB 4.0 is adding (multi-collection) multi-document transactions: link

    0 讨论(0)
提交回复
热议问题