2013-05-03 13 views
11

Quando uso transaction() aggiornare una posizione, i dati in quella posizione è ritorni null anche se la posizione aventi alcuni dati.Firebase api chiamata transazione di dati corrente è null

Ho provato transaction()dopo aver letto i dati nella stessa posizione in cui il tempo sta dando tutti i dati in quella posizione.

Come posso utilizzare transaction() se il caso è come sopra?

risposta

20

Le transazioni funzionano come SimpleDB di Amazon o un cluster di database semplificato. Vale a dire, sono "alla fine coerenti" piuttosto che garantiti coerenti.

Pertanto, quando si utilizzano le transazioni, la funzione di elaborazione può essere richiamata più volte con un valore locale (in alcuni casi nullo se non è mai stato recuperato) e quindi di nuovo con il valore sincronizzato (qualunque cosa si trovi sul server).

Esempio:

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 

}); 

Questa è davvero la mentalità con cui si deve affrontare delle transazioni in ogni modo. Dovresti sempre aspettarti più chiamate, poiché la prima transazione potrebbe scontrarsi con un'altra modifica e essere respinta. Non è possibile utilizzare il metodo di elaborazione di una transazione per recuperare il valore del server (sebbene sia possibile leggerlo dal callback di successo).

Prevenire l'evento innescato localmente

Quando la transazione avviene, un evento locale viene attivato prima che raggiunga il server per la compensazione di latenza. Se la transazione fallisce, l'evento locale verrà ripristinato (viene attivato un evento di modifica o rimozione).

È possibile utilizzare la proprietà on transactionsapplyLocally per sovrascrivere questo comportamento, che rallenta i risultati locali ma garantisce che solo il valore del server venga attivato localmente.

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

Grazie, ho usato la transazione quasi 3 giorni dopo i dati inseriti. Quindi tu dici di usare la transazione per prima cosa, dobbiamo controllare quella posizione se esiste o meno un valore? – Ashok

+0

"Eventually persistent" non ha nulla a che fare con la lunghezza che è stata sul server, solo la lunghezza che è stata sul client - non è sul client finché non lo chiedi. Non è necessario necessariamente verificare che esista un valore, accetta solo che la funzione possa essere chiamata più volte e che venga "eventualmente" chiamata con il valore del server. – Kato

+0

@Kato Prendo atto che la transazione sarebbe una cosa negativa per un server Node da utilizzare per decrementare il saldo di un utente?Come se un altro server di nodo effettuasse una scrittura in anticipo, allora voglio scrivere la stessa cosa (quindi impostare sarebbe meglio?) –

7

è necessario seguire questo schema:

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 solito restituisce un valore nullo durante il recupero di una chiave per la prima volta, ma, mentre il risparmio viene verificato se il nuovo valore è simile al valore di età superiore o non. In caso contrario, firebase eseguirà di nuovo l'intero processo e questa volta il server restituirà il valore corretto.

Aggiunta di un null controllo e restituendo un valore totalmente inaspettato (0 in questo caso) farà incendi il ciclo nuovamente.

+1

questa dovrebbe essere la risposta corretta. – martinjbaker

+0

Invece di restituire 0, è possibile tornare indefinito per interrompere la transazione. "Se viene restituito un valore non definito (vale a dire che si restituisce senza argomenti) la transazione verrà interrotta e i dati in questa posizione non verranno modificati." https://firebase.google.com/docs/reference/admin/node/admin.database.Reference#transaction –

+0

Non so se qualcosa è cambiato in Firebase da quando è stata scritta questa risposta, ma se restituisco undefined o niente , Firebase si blocca per 60 secondi e poi scade. Immagino che il risultato netto sia lo stesso, ma non sembra una buona cosa da fare. –

Problemi correlati