Jakie macie doświadczenia z transakcyjnością w MongoDB? Załóżmy, że mamy kolekcję użytkowników i każdy z nich ma swój portfel z listą transakcji tj. wpłaty/wypłaty. Kwestia jest taka by optymalnie i atomowo dla użytkownika A wypłacić x środków a dla użytkownika B wpłacić x środków (przelew x A -> B) czyli update na 2 dokumentach. Czy mongo nada się do takiej operacji?
A springowe @Transactional
tego nie zapewnia? Z tego co kojarzę to mongo od jakiejś wersji wspiera transakcyjność.
Tak bodajże od wersji 7 wspiera. Jestem jeszcze przed wyborem bazy danych i mongo ogólnie świetnie mi pasuje poza przypadkiem gdzie użytkownicy przelewają sobie pieniądze. Zastanawiam się czy jak w grę wchodzi kasa czy to będzie bezpieczne rozwiązanie czy nie lepiej wykorzystać w tym przypadku relacyjną bazę. Zastanawiam się też nad modelem tj. czy mieć kolekcję użytkowników i każdy dokument miałby listę transakcji/operacji na portfelu czy lepiej żeby było tylko saldo środków i obok jakaś kolekcja „transaction_log”.
A jakie masz argumenty za Mongo?
EDIT: I nie tylko za Mongo per se, ale ogolnie nosql vs sql?
A nie powinieneś trzymać listy transakcji i na tej podstawie wyliczać stan portfeli? BTW. Kumpel pracuje w jednym amerykasnkim banku który wynosi się z Mongo do Oracle
Argumenty mam takie, że mongo da mi elastyczność w postaci modelu, który nie musi być aż tak restrykcyjny jak w rdbms np. w moim przypadku różne ogłoszenia które będą mieć wiele atrybutów w tym jakichś zagnieżdżonych mogą być zapisywane jako całość w jednym dokumencie gdzie w sql musiałbym kombinować i za każdym razem jakby trzeba było coś dodać musiałbym pewnie kolejną tabelkę z kluczem obcym dodać a jak wiadomo joiny słabo się skalują.
@Adin Tj. napisałem jednym z pomysłów jest aby każdy użytkownik miał listę transakcji na swoim portfelu i wtedy portfel byłby takim argegatem i odtwarzał stan na podstawie transakcji. Z drugiej strony zastanawiam się czy nie wystarczy saldo i w innej kolekcji odkładać wszystkie transakcje na potrzeby audytu. Muszę też wziąć pod uwagę co jeśli 2 użytkowników przelewa w tym samym czasie do 3 czyli jakiś optimistic locking musiałbym zastosować.
lukascode napisał(a):
Argumenty mam takie, że mongo da mi elastyczność w postaci modelu, który nie musi być aż tak restrykcyjny jak w rdbms np. w moim przypadku różne ogłoszenia które będą mieć wiele atrybutów w tym jakichś zagnieżdżonych mogą być zapisywane jako całość w jednym dokumencie gdzie w sql musiałbym kombinować i za każdym razem jakby trzeba było coś dodać musiałbym pewnie kolejną tabelkę z kluczem obcym dodać a jak wiadomo joiny słabo się skalują.
Kolumna z JSONem jest rozwiązaniem tego problemu
slsy napisał(a):
Kolumna z JSONem jest rozwiązaniem tego problemu
A jak potem zrobisz zapytanie na podstawie atrybutów, które są głęboko zaszyte w tym jsonie?
lukascode napisał(a):
slsy napisał(a):
Kolumna z JSONem jest rozwiązaniem tego problemu
A jak potem zrobisz zapytanie na podstawie atrybutów, które są głęboko zaszyte w tym jsonie?
Normalnie
@stivens Tylko pytanie po co tak się bawić skoro właśnie bazy typu mongo zostały stworzone do takich zastosowań?
lukascode napisał(a):
@stivens Tylko pytanie po co tak się bawić skoro właśnie bazy typu mongo zostały stworzone do takich zastosowań?
Pyta gosc, ktory pyta o transakcje w nosql.
Tylko pytanie po co tak się bawić skoro masz postgresa do takich zastosowan?
Pytam bo wsparcie jest dlatego chciałem się dowiedzieć jak w praktyce się to sprawdza innym żeby nie wbić się na mine.
I chcę też uniknąć dodatkowej złożoności w postaci utrzymywania 2 baz danych.
Twój problem brzmi jak typowy domowy pet projekt więc możesz puścić wodze fantazji i spróbować zaimlementować port do bazy danych na dwa różne sposoby: raz z wykorzystaniem mongo a raz z wykorzystaniem jakieś bazy sql'owej.
A jeżeli nie jest to petprojekt tylko realny task w pracy to with all due respect po pierwszym poście mam wrażenie, że nie powinieneś decydować ani jak zaimplementować przelewanie hajsu (przykład z atomową transakcją raczej nijak się ma do rzeczywistych systemów obracającychg środkami - jest to taki naiwny przykład by wskazać jak działa atomowość transakcji w tutorialach od hinusów) ani jakiej bazy do tego użyć.
@RequiredNickname Ani jedno ani drugie. Dlaczego mam nie decydować? Moja aplikacja płace za chmure to robie co chce… Nie pytałem o ocenę moich kompetencji tylko konkretną rekomendację.
Bez sensu osobny audyt transakcji który może być niespójny. Lepiej mieć spis transakcji, a potem tylko zlecić aktualizację stanów portfeli na podstawie tej listy i ta aktualizacja nie musi się już dziać atomowo i w transakcji. Wystarczy zaktualizować na raz jeden dokument więc cały problem odpada. Mam wrażenie że w ten sposób mniej więcej to działa w bankach bo często przelanie środków nawet między swoimi dwoma rachunkami nie jest natychmiastowe, wręcz banki pozwalają wyjść na minus przy robieniu szybkich transakcji i nie jest to wtedy problem banku tylko klienta bo musi płacić karę. Jeśli nie możesz dopuścić do negatywnego salda to wystarczy że weźmiesz pod uwagę nierozstrzygnięte ujemne transkacje podczas zlecania i zablokować taki przelew.
Pytanie jak poważna jest ta aplikacja, czy dotyka realnych pieniędzy i o jakich kwotach mowa, bo jeśli to nie jest tylko jakaś gra to lepiej się poradzić kogoś kto ma doświadczenie w takich sprawach.
lukascode napisał(a):
Argumenty mam takie, że mongo da mi elastyczność w postaci modelu, który nie musi być aż tak restrykcyjny jak w rdbms np. w moim przypadku różne ogłoszenia które będą mieć wiele atrybutów w tym jakichś zagnieżdżonych mogą być zapisywane jako całość w jednym dokumencie gdzie w sql musiałbym kombinować i za każdym razem jakby trzeba było coś dodać musiałbym pewnie kolejną tabelkę z kluczem obcym dodać a jak wiadomo joiny słabo się skalują.
że nie znasz SQLa
@Adin Tj. napisałem jednym z pomysłów jest aby każdy użytkownik miał listę transakcji na swoim portfelu i wtedy portfel byłby takim argegatem i odtwarzał stan na podstawie transakcji. Z drugiej strony zastanawiam się czy nie wystarczy saldo i w innej kolekcji odkładać wszystkie transakcje na potrzeby audytu. Muszę też wziąć pod uwagę co jeśli 2 użytkowników przelewa w tym samym czasie do 3 czyli jakiś optimistic locking musiałbym zastosować.
krypto?
lukascode napisał(a):
@RequiredNickname Ani jedno ani drugie. Dlaczego mam nie decydować? Moja aplikacja płace za chmure to robie co chce… Nie pytałem o ocenę moich kompetencji tylko konkretną rekomendację.
No to jak jeszcze trochę podrośniesz to może zrozumiesz że w prawdziwym świecie technologie dobiera się do problemu, z problemem przychodzi biznes i zazwyczaj są nieco bardziej skomplikowane a już na pewno nie polegają na wyborze bazy „bo transakcyjna”.
Tłumacząc to na polski bo jednak mam obawy że nie zrozumiesz: wybór odpowiedniej technologii zawsze powinienem być podyktowany analizą problemu, powinny być brane pod uwagę kompetencje zespołu oraz powinna byc świadomość z czym się wiąże wybór tej a nie innej technologii.
Ty nie przyszedłeś ze sprecyzowanym rzeczywistym problemem tylko pet projektem dlatego Ci napisałem żebyś sobie zaimplementował to na dwa różne sposoby skoro chcesz się pouczyć.
Więc z łaski swojej nie unoś się gdy Ci wujek RequiredNickname daje dobre rady :-)
wybór odpowiedniej technologii zawsze powinienem być podyktowany analizą problemu, powinny być brane pod uwagę kompetencje zespołu oraz powinna byc świadomość z czym się wiąże wybór tej a nie innej technologii.
I właśnie to się dzieje czyli rzucam jakieś pomysły i analizujemy .
MongoDB - transakcje są tam tylko na agregatach to jest całych dokumentach. Nie ma tam czegoś takiego jak transakcje pomiędzy dokumentami.
Obawiam się że jedyne na co możesz liczyć to eventual consistency dla GUI.
Samo przetwarzanie transakcji zwykle robi się batchowo, w końcu nawet przelewy nie przychodzą real time.
Nawet jeśli użytkownik w GUI zobaczy więcej niż ma na koncie to w końcu przetwarzanie batchowe przetworzy wszystkie transakcje i odpowiednio ustawi kwoty w bazie.
Zeby to wszystko działało trzeba mieć optymistic concurrency czyli lockować updatey na agreagatch po jakimś timestamp atomowym lub versionNumber.
Czas pójść po rozum do głowy i postawić jak pan Bóg przykazał Postgresa lub MySQL i tam przenieść dane o stanie kont. Reszta danych może nadal być w MongoDB ale te dane które wymagają transakcyjności i bezpieczeństwa warto jednak trzymać w boring SQLach...
Dziwne, że jeszcze nikt nie wrzucił:
@ArchitektSpaghetti +1 za słuszną obserwację co do atomowości.
Nie używam mongo, więc nie hejtuję, ale i też nie wiem czy to prawda co producent wypisuje ;-)
Natomiast producent chwali się, że produkt jest ACID compliant, wspiera multi-document transactions i distributed transactions:
- https://www.mongodb.com/resources/products/capabilities/acid-compliance
- 4.0 -> multi document transactions https://www.mongodb.com/blog/post/mongodb-multi-document-acid-transactions-general-availability
- 4.2 -> distributed trasactions https://www.mongodb.com/company/newsroom/press-releases/mongodb-42-adds-distributed-transactions-field-level-encryption-updated-kubernetes-operator-and-more-to-the-leading-modern-general-purpose-database
Co więcej, pokazują przykłady np. w Javie -> https://www.mongodb.com/developer/languages/java/java-multi-doc-acid-transactions/