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

Я понимаю, что MongoDB, под этимСама природа, не правда ли?и, вероятно, никогда не будет поддерживать такие транзакции. Тем не менее, я обнаружил, что мне нужно использовать их несколько ограниченным образом, поэтому ямы придумали следующее решение, и ямне интересно:это лучший способ сделать это, и можно ли его улучшить? (прежде чем я пойду и осуществлю это в моем приложении!)

Очевидно, что транзакция контролируется через приложение (в моем случае, веб-приложение 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: Для каждого документа, на который влияет эта транзакция:

Задаватьlock_status вtrue (к 'замок' документ от изменения)Задаватьdata_old а такжеdata_new к их старым и новым ценностямЗадаватьchange_complete вfalseЗадаватьtransaction_id в ObjectId изtransaction документ, который мы только что сделали

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

Замените все затронутые поля в этом документе наdata_new ценностиЗадаватьchange_complete вtrue

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

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

удалитьdata_old а такжеdata_new, как они'больше не нужнызадаватьlock_status вfalse (чтобы разблокировать документ)

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

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

Есть ли явная ошибка в этой логике, что япропустили или упустили из виду? Есть ли более эффективный способ сделать это (например, меньше писать / читать из базы данных)?

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

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