25

transaction()場所を更新するために使用すると、その場所にデータがあるにもかかわらず、その場所のデータがnull を返します。

その場所ですべてのデータを提供しているときに、同じ場所でtransaction() データを読み取った後に試しました。

transaction()上記のような場合、どのように使えばよいでしょうか?

4

3 に答える 3

30

トランザクションは、Amazon の SimpleDB またはデータベースのシャード クラスターのように機能します。つまり、一貫性が保証されるのではなく、「最終的に一貫性がある」ということです。

そのため、トランザクションを使用している場合、処理関数がローカル値 (取得されていない場合は null) で複数回呼び出され、同期された値 (サーバー上にあるものは何でも) で再度呼び出される場合があります。

例:

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

});

これは、とにかくトランザクションにアプローチしなければならない考え方です。最初のトランザクションが別の変更と衝突して拒否される可能性があるため、常に複数の呼び出しを想定する必要があります。トランザクションの処理メソッドを使用してサーバーの値を取得することはできません (ただし、成功のコールバックから読み取ることはできます)。

ローカルでトリガーされるイベントの防止

トランザクションが発生すると、遅延補償のためにサーバーに到達する前にローカル イベントがトリガーされます。トランザクションが失敗した場合、ローカル イベントは元に戻されます (変更または削除イベントがトリガーされます)。

トランザクションapplyLocallyのプロパティを使用してこの動作をオーバーライドできます。これにより、ローカルの結果が遅くなりますが、サーバーの値のみがローカルでトリガーされるようになります。

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);
于 2013-05-03T15:19:40.397 に答える
20

次のパターンに従う必要があります。

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 は通常、キーを初めて取得するときに null 値を返しますが、保存するときに、新しい値が古い値と似ているかどうかを確認します。そうでない場合、firebase はプロセス全体を再度実行し、今度はサーバーから正しい値が返されます。

チェックを追加しnullてまったく予期しない値 (この場合) を返す0と、firebase は再びサイクルを実行します。

于 2016-08-28T18:07:30.563 に答える