Multi-collection, multi-document „transakcje” w MongoDB

Zdaję sobie sprawę, że MongoDB, ze względu na swoją naturę, nie obsługuje i prawdopodobnie nigdy nie będzie obsługiwać tego rodzaju transakcji. Jednak odkryłem, że muszę ich używać w nieco ograniczony sposób, więc wymyśliłem następujące rozwiązanie i zastanawiam się:czy jest to najlepszy sposób na zrobienie tego i czy można go ulepszyć? (zanim przejdę do implementacji w mojej aplikacji!)

Oczywiście transakcja jest kontrolowana przez aplikację (w moim przypadku jest to aplikacja internetowa Pythona). Dla każdego dokumentu w tej transakcji (w dowolnej kolekcji) dodawane są następujące pola:

'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

Ponadto istniejetransaction kolekcja przechowująca dokumenty opisujące każdą trwającą transakcję. Wyglądają na:

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

A oto logika tego procesu. Mam nadzieję, że działa w taki sposób, że jeśli zostanie przerwany lub ulegnie awarii w inny sposób, może zostać poprawnie przywrócony.

1: Ustawićtransaction dokument

2: Dla każdego dokumentu, na który ma wpływ ta transakcja:

Zestawlock_status dotrue (aby „zablokować” dokument przed modyfikacją)Zestawdata_old idata_new do ich starych i nowych wartościZestawchange_complete dofalseZestawtransaction_id do celutransaction dokument, który właśnie zrobiliśmy

3: Przeprowadź aktualizację. Dla każdego dokumentu, którego dotyczy problem:

Zastąp wszystkie pola w tym dokumencie za pomocądata_new wartościZestawchange_complete dotrue

4: Ustawtransaction dokumentstatus dotrue (ponieważ wszystkie dane zostały pomyślnie zmodyfikowane)

5: Dla każdego dokumentu objętego transakcją wykonaj kilka czynności porządkowych:

usunąćdata_old idata_new, ponieważ nie są już potrzebnezestawlock_status dofalse (aby odblokować dokument)

6: Usunąćtransaction dokument skonfigurowany w kroku 1 (lub zgodnie z sugestią zaznacz jako kompletny)

Myślę, że logicznie działa w taki sposób, że jeśli zawiedzie w dowolnym momencie, wszystkie dane mogą być albo wycofane, albo transakcja może być kontynuowana (w zależności od tego, co chcesz zrobić). Oczywiście wszystkie rollback / recovery / etc. jest wykonywane przez aplikację, a nie przez bazę danych, przy użyciutransaction dokumenty i dokumenty w innych kolekcjach z tym identyfikatorem transakcji.

Czy w tej logice jest jakiś rażący błąd, który przeoczyłem lub przeoczyłem? Czy istnieje skuteczniejszy sposób na to (np. Mniej pisania / czytania z bazy danych)?

questionAnswers(3)

yourAnswerToTheQuestion