Многочисленные, многодокументные «транзакции» в MongoDB

Я понимаю, что MongoDB по самой своей природе не поддерживает и, вероятно, никогда не будет поддерживать такие транзакции. Однако я обнаружил, что мне нужно использовать их в некоторой степени, поэтому я пришел к следующему решению, и мне интересно:is this the best way of doing it, and can it be improved upon? (прежде чем я пойду и осуществлю это в моем приложении!)

Очевидно, что транзакция контролируется через приложение (в моем случае, веб-приложение Python). Для каждого документа в этой транзакции (в любой коллекции) добавляются следующие поля:

'lock_status': bool (true = locked, false = unlocked),
'data_old': dict (of any old values - current values really - that are being changed),
'data_new': dict (of values replacing the old (current) values - should be an identical list to data_old),
'change_complete': bool (true = the update to this specific document has occurred and was successful),
'transaction_id': ObjectId of the parent transaction

Кроме того, естьtransaction коллекция, в которой хранятся документы, подробно описывающие каждую транзакцию. Они похожи:

{
    '_id': ObjectId,
    'date_added': datetime,
    'status': bool (true = all changes successful, false = in progress),
    'collections': array of collection names involved in the transaction
}

А вот и логика процесса. Надеемся, что он работает таким образом, что, если он прервался или потерпит неудачу каким-либо другим способом, он может быть откачен должным образом.

1: Настроитьtransaction документ

2: Для каждого документа, на который влияет эта транзакция:

Set lock_status to true (to 'lock' the document from being modified) Set data_old and data_new to their old and new values Set change_complete to false Set transaction_id to the ObjectId of the transaction document we just made

3: Выполните обновление. Для каждого затронутого документа:

Replace any affected fields in that document with the data_new values Set change_complete to true

4: Установитьtransaction Документ & APOS; sstatus вtrue (так как все данные были успешно изменены)

5: Для каждого документа, затронутого транзакцией, выполните некоторую очистку:

remove the data_old and data_new, as they're no longer needed set lock_status to false (to unlock the document)

6: Удалитьtransaction документ, созданный на шаге 1 (или, как предлагается, пометьте его как завершенный)

Я думаю, что это логически работает таким образом, что если в любой момент происходит сбой, все данные можно откатить или продолжить транзакцию (в зависимости от того, что вы хотите сделать). Очевидно, что все откат / восстановление / и т. Д. выполняется приложением, а не базой данных, используяtransaction документы и документы в других коллекциях с этимaction_id.

Is there any glaring error in this logic that I've missed or overlooked? Is there a more efficient way of going about it (e.g. less writing/reading from the database)?

Ответы на вопрос(3)

Ваш ответ на вопрос