2013-07-03 17 views
38

Firebase pozwala na aktualizację zasobu transactionally. Jak rozumiem, klient robi to wysyłając żądania wysyłania na serwer, mówiąc: "Jeśli stara wartość to X, zrób nową wartość Y". Jeśli dojdzie do rywalizacji, serwer może odrzucić wiele aktualizacji od klienta, dopóki nie zostanie zaakceptowany.Firebase: Jak aktualizować wiele zasobów atomowo?

Co, jeśli chcę zaktualizować wiele zasobów atomowo?

Co się stanie, jeśli pierwsza aktualizacja zostanie zaakceptowana, a następnie klient zostanie odłączony przed zaakceptowaniem drugiej aktualizacji. Czy istnieje sposób na umieszczenie wielu aktualizacji w transakcji atomowej? Jeśli nie, czy istnieje idiomatyczne rozwiązanie tego problemu?

Odpowiedz

44

UPDATE

Jest to teraz możliwe, aby zaktualizować wiele lokalizacji atomowo. Aby uzyskać szczegółowe informacje, patrz this blog post.

var mergedUpdate = {}; 
mergedUpdate[ 'users/' + userId + '/widgets/' + widgetId ] = true; 
mergedUpdate[ 'widgets/' + widgetId ] = widgetData; 

var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/"); 
ref.update(mergedUpdate); 

nie egzekwować dane transakcyjne (jeśli wartość jest obecnie X, Y to zrobić), ale ta część może zostać przeniesiony do security rules. Na przykład, jeśli chcemy, aby zaktualizować dwa liczniki w tym samym czasie, możemy dodać reguły następująco:

{ 
    "counter1": { 
    ".validate": "newData.val() === (data.val()||0)+1" 
    }, 

    "counter2"1 { 
    ".validate": "newData.val() === (data.val()||0)+1" 
    } 
} 

Teraz możemy próbować tę samą aktualizację multi-path jak wyżej. Jeśli wartości zmieniły się od ostatniego odczytania ich z serwera, próba zakończy się niepowodzeniem. Możemy sprawdzić if(error.code === 'PERMISSION_DENIED') { ... }, aby sprawdzić, czy niepowodzenie było wynikiem sprawdzania poprawności, i ponów próbę.

ORIGINAL POST

Jedynym sposobem, aby to zrobić, to uruchomić transakcję w sprawie wspólnego przodka.

Na przykład, jeśli chcesz zaktualizować/a/b/c i/a/x/y, możesz uruchomić transakcję w/a i zmienić obie wartości.

Wadą tego podejścia jest to, że może być kosztowne w przypadku sieciowych operacji wejścia/wyjścia, ponieważ wszystkie dane w ramach transakcji muszą zostać pobrane, a następnie przesłane na serwer.

Bardziej skomplikowana, ale potencjalnie bardziej skuteczna metoda, którą warto rozważyć, to restrukturyzacja danych, aby zamiast zapisywać rzeczywiste wartości, przechowywać historię zmian. Na przykład, jeśli przechowujesz informacje o saldzie bankowym, możesz przechowywać historię depozytów i wypłat. Następnie, gdy chcesz uzyskać równowagę, odtwarzasz całą historię i obliczasz saldo końcowe.

Piękno tego podejścia polega na tym, że umożliwia wykonywanie aktualizacji atomowych. Na przykład, jeśli przesyłasz pieniądze z konta A na konto B, wystarczy, że dodasz element na końcu dziennika, mówiąc: "przenieś z konta A na konto N dolarów". Dołączanie tego pojedynczego elementu jest operacją atomową.

Jest to podejście, które stosujemy za pomocą wspólnego edytora tekstu Firepad.

+0

Dziękuję za odpowiedź. Konceptualnie lubię zapisywać nowe transakcje zamiast aktualizować je w miejscu, ale myślę, że jest to wykonalne tylko z perspektywy wydajności, jeśli istnieje funkcja materializacji zapytań. Odtwarzanie całej historii będzie powolne. –

+0

Nie ma jeszcze jednego (przynajmniej jeszcze nie), ale zdecydowanie widzimy, jak to by było przydatne! Na razie możesz zmaterializować zapytanie na kliencie i zapisać je z powrotem do "punktu kontrolnego" w Firebase (tak działa Firepad), lub możesz mieć serwer node.js lub Java, gdzieś działający jako klient Firebase, który materializuje się to dla Ciebie. –

+0

HI! Thanx, ale właśnie próbowałem tego i dostałem błąd: "Linia 10: Lewy operand || musi być boolean." Czy czegoś brakuje? Używam Firebase 3.0 ... –

0

istnieje inny sposób .... bardzo uciążliwe ... i naprawdę nie transakcje ...

Jak Firebase pozwala atomowo zmienia się od wartości, można utworzyć blokady lub semafora ze znaczeniem „rozpoczął transakcja na zasobach x, y i z "...Oczywiście nie jest to prawdziwa transakcja, ponieważ nie blokuje zasobów, część z zamka. Moglibyśmy nazwać to transakcją konwencją. Klienci muszą wiedzieć, że gdy blokada jest zajęta, nie powinni zmieniać zasobów x, yi z ....

+2

to rozłącza się, gdy dwóch klientów jednocześnie prosi o semafor. nie jest to prawdziwy zamek, więc nie rozwiązuje problemu współbieżności, tylko zmniejsza szanse. –

Powiązane problemy