2013-05-03 4 views
11

Gdy używam transaction() zaktualizować lokalizację, dane w tej lokalizacji jest powrocie zerowy chociaż lokalizacja o jakieś dane.Firebase transakcja wywołanie API aktualne dane jest null

Próbowałem transaction()po odczytaniu danych w tym samym miejscu, w którym podano wszystkie dane w tej lokalizacji.

Jak mogę użyć numeru transaction(), jeśli sprawa wygląda tak, jak powyżej?

Odpowiedz

20

Transakcje działają w trybie SimpleDB firmy Amazon lub w zbitym klastrze baz danych. To znaczy, że są "ostatecznie zgodne", a nie gwarantowane spójne.

Tak więc podczas korzystania z transakcji funkcja przetwarzania może zostać wywołana więcej niż jeden raz z wartością lokalną (w niektórych przypadkach null, jeśli nigdy nie została pobrana), a następnie ponownie z wartością zsynchronizowaną (cokolwiek jest na serwerze).

Przykład:

pathRef.transaction(function(curValue) { 

    // this part is eventually consistent and may be called several times 

}, function(error, committed, ss) { 

    // this part is guaranteed consistent and will match the final value set 

}); 

To jest naprawdę myślenia, z którym trzeba podejść transakcję tak czy inaczej. Powinieneś zawsze oczekiwać wielu połączeń, ponieważ pierwsza transakcja może kolidować z inną zmianą i zostać odrzucona. Nie można użyć metody przetwarzania transakcji do pobrania wartości serwera (chociaż można ją odczytać z wywołania zwrotnego sukcesu).

Zapobieganie lokalnie wywołało zdarzenie

Gdy transakcja dojdzie, miejscowy zdarzenie jest wywoływane zanim dotrze do serwera za opóźnienia rekompensaty. Jeśli transakcja się nie powiedzie, zdarzenie lokalne zostanie cofnięte (wywoływane jest zdarzenie change lub remove).

Można użyć właściwości applyLocallyon transactions, aby zastąpić to zachowanie, co powoduje spowolnienie wyników lokalnych, ale zapewnia, że ​​tylko wartość serwera jest uruchamiana lokalnie.

pathRef.transaction(function(curValue) { 

    // this is still called multiple times 

}, function(error, committed, ss) { 

    // this part is guaranteed consistent and will match the final value set 

}, 
    // by providing a third argument of `true`, no local event 
    // is generated with the locally cached value. 
true); 
+0

Dzięki, użyłem transakcji prawie 3 dni po wstawieniu danych. Mówisz więc, że najpierw musisz użyć transakcji, aby sprawdzić, czy dana wartość istnieje, czy nie? – Ashok

+0

"W końcu trwały" nie ma nic wspólnego z długością, na jakiej znajdował się na serwerze, tylko z długością, na jakiej znajdował się na kliencie - nie ma go na kliencie, dopóki o to nie poprosisz. Nie musisz koniecznie sprawdzać, czy istnieje wartość, po prostu zaakceptuj, że funkcja może być wywołana wiele razy i "w końcu" zostanie wywołana z wartością serwera. – Kato

+0

@Kato Podejrzewam, że ta transakcja byłaby zła dla serwera Node, aby obniżyć saldo użytkownika?Tak jak gdyby wcześniej inny serwer węzła zapisywał, to chcę, żeby zapisał tę samą rzecz (więc lepiej byłoby ustawić?) –

7

Trzeba się do tego wzoru:

var pinRef = firebase.database().ref('vm-pin-generator'); 
pinRef.transaction(function(oldPin) { 
    // Check if the result is NOT NULL: 
    if (oldPin != null) { 
     return localPinIncrementor(oldPin); 
    } else { 
     // Return a value that is totally different 
     // from what is saved on the server at this address: 
     return 0; 
    } 
}, function(error, committed, snapshot) { 
    if (error) { 
     console.log("error in transaction"); 
    } else if (!committed) { 
     console.log("transaction not committed"); 
    } else { 
     console.log("Transaction Committed"); 
    } 
}, true); 

Firebase zwykle zwraca wartość null podczas pobierania klucza po raz pierwszy, ale podczas zapisywania sprawdza, czy nowa wartość jest podobna do starszej wartości lub nie. Jeśli nie, baza ogniowa uruchomi cały proces ponownie i tym razem serwer zwróci poprawną wartość.

Dodanie do sprawdzenia i zwrócenie całkowicie nieoczekiwanej wartości (0) spowoduje, że baza ogniowa uruchomi cykl ponownie.

+1

to powinna być poprawna odpowiedź. – martinjbaker

+0

Zamiast zwracania 0, możesz wrócić undefined, aby przerwać transakcję. "Jeśli zostanie zwrócone niezdefiniowane (tzn. Zwrócisz bez żadnych argumentów), transakcja zostanie przerwana, a dane w tej lokalizacji nie zostaną zmienione." https://firebase.google.com/docs/reference/admin/node/admin.database.Reference#transaction –

+0

Nie wiem, czy coś się zmieniło w Firebase, ponieważ ta odpowiedź została napisana, ale jeśli wrócę niezdefiniowany lub nic , Firebase wisi na 60 sekund, a następnie wygasa. Sądzę, że wynik netto jest taki sam, ale nie wydaje się to dobrym wyjściem. –

Powiązane problemy