交易中的数据为空 [英] Data in transaction is null

查看:173
本文介绍了交易中的数据为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个交易的问题。事务中的数据总是空的,更新处理程序只调用一次。 文档说:


为了达到这个目的,你需要传递一个更新函数
来将当前值转换成一个新的值。如果另一个
客户端在新值写入成功
之前写入了该位置,则将使用新的
当前值再次调用更新函数,并重新写入。这会重复发生
,直到你的写入成功而没有冲突,或者通过不从你的更新函数返回一个值来中止
的交易。

现在我知道现在没有其他客户访问该位置了。其次,如果我正确地阅读了文档,应该多次调用updateCounters函数,如果它检索和更新数据失败。



另外 - 如果我把条件 if(counters === null)执行将失败,因为计数器是 null ,但是在后续的尝试中事务完成 - 检索数据并进行更新。

简单的曾经设置在这个位置工作得很好,但是不安全。



请问我错过了什么?



这里是代码



<$ p $ ($)$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $。

$ {
console.log('in transaction counters:',counters);
counters.comments = counters.comments + 1;
return counters;
}
},函数(错误,提交,ss){
if(error){
console.log('transaction aborted');
// TODO错误处理
} else if(!committed){
console.log('counters is null - why?');
} else {
console.log('counter increased ',ss.val());
}
},true);

这里是位置数据

<$





$ b $ $ $ $通过在<$ code> undefined 中返回


解决方案 c $ c> if(... === null)块,你正在中止交易。因此,它永远不会向服务器发送一个尝试,从来没有意识到本地缓存的值不是远程的,并且不会再更新的值(来自服务器的实际值)。

事实证明,提交 false ,错误是在您的成功函数中,如果事务被中止,则发生空



事务工作如下:


  • 将本地缓存的值传递到处理函数中,如果您从未从服务器获取该数据,则本地缓存的值为 null (该路径最可能的远程值)
  • 从处理函数获得返回值,如果该值为 undefined 中止事务,否则,创建一个当前值的散列(null),并且如果本地散列匹配,则将新值(由处理函数返回)传递给服务器
  • 服务器的curre nt hash,应用更改,服务器返回成功结果如果服务器事务未应用,服务器返回新值,然后客户端再次使用更新后的值调用处理函数从服务器直到成功

  • 当最终成功时,发生不可恢复的错误,或者事务被中止(通过返回未定义的处理函数),然后调用成功方法的结果。 / li>


所以为了使这个工作,显然你不能放弃第一个返回值的事务。

完成相同结果的一个解决方法是,尽管它是耦合的,而不是像性能或者恰当的那样使用事务,一个一次('value',...)回调,这将确保它在本地被缓存在运行事务之前


I have a problem with transactions. The data in the transaction is always null and the update handler is called only singe once. The documentation says :

To accomplish this, you pass transaction() an update function which is used to transform the current value into a new value. If another client writes to the location before your new value is successfully written, your update function will be called again with the new current value, and the write will be retried. This will happen repeatedly until your write succeeds without conflict or you abort the transaction by not returning a value from your update function

Now I know that there is no other client accessing the location right now. Secondly if I read the documentation correctly the updateCounters function should be called multiple times should it fail to retrieve and update data.

The other thing - if I take out the condition if (counters === null) the execution will fail as counters is null but on a subsequent attempt the transaction finishes fine - retrieves data and does the update.

simple once - set on this location work just fine but it is not safe.

Please what do I miss?

here is the code

self.myRef.child('counters')
  .transaction(function updateCounters(counters){
    if (counters === null) {
      return;
    }
    else {
      console.log('in transaction counters:', counters);
      counters.comments = counters.comments + 1;
      return counters;
    }
  }, function(error, committed, ss){
    if (error) {
      console.log('transaction aborted');
      // TODO error handling
    } else if (!committed){
      console.log('counters are null - why?');
    } else {
      console.log('counter increased',ss.val());
    }
  }, true);

here is the data in the location

counters:{
  comments: 1,
  alerts: 3,
  ...
}

解决方案

By returning undefined in your if( ... === null ) block, you are aborting the transaction. Thus it never sends an attempt to the server, never realizes the locally cached value is not the same as remote, and never retries with the updated value (the actual value from the server).

This is confirmed by the fact that committed is false and the error is null in your success function, which occurs if the transaction is aborted.

Transactions work as follows:

  • pass the locally cached value into the processing function, if you have never fetched this data from the server, then the locally cached value is null (the most likely remote value for that path)
  • get the return value from the processing function, if that value is undefined abort the transaction, otherwise, create a hash of the current value (null) and pass that and the new value (returned by processing function) to the server
  • if the local hash matches the server's current hash, the change is applied and the server returns a success result
  • if the server transaction is not applied, server returns the new value, client then calls the processing function again with the updated value from the server until successful
  • when ultimately successful, and unrecoverable error occurs, or the transaction is aborted (by returning undefined from the processing function) then the success method is called with the results.

So to make this work, obviously you can't abort the transaction on the first returned value.

One workaround to accomplish the same result--although it is coupled and not as performant or appropriate as just using the transactions as designed--would be to wrap the transaction in a once('value', ...) callback, which would ensure it's cached locally before running the transaction.

这篇关于交易中的数据为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆