事务中的数据为空
Data in transaction is null
我有交易问题。事务中的数据始终为空,更新处理程序仅被调用一次。 documentation 表示:
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
现在我知道现在没有其他客户端访问该位置。其次,如果我正确阅读了文档,如果无法检索和更新数据,应该多次调用 updateCounters 函数。
另一件事 - 如果我取出条件 if (counters === null)
执行将失败,因为计数器是 null
但在随后的尝试中事务完成正常 - 检索数据并进行更新。
简单 once - set
在这个位置工作得很好,但不安全。
请问我错过了什么?
这是代码
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);
这里是位置
中的数据
counters:{
comments: 1,
alerts: 3,
...
}
通过在您的 if( ... === null )
块中 returning undefined
,您将中止交易。因此它永远不会向服务器发送尝试,永远不会意识到本地缓存的值与远程不同,并且永远不会使用更新后的值(来自服务器的实际值)重试。
committed
是 false
并且您的成功函数中的错误是 null
这一事实证实了这一点,如果交易被中止,就会发生这种情况。
交易工作如下:
- 将本地缓存值传递给处理函数,如果您从未从服务器获取此数据,则本地缓存值是
null
(该路径最可能的远程值)
- 从处理函数中获取 return 值,如果该值是
undefined
则中止事务,否则,创建当前值(null)的散列并传递该值和新值(return由处理函数编辑)到服务器
- 如果本地散列与服务器的当前散列匹配,则应用更改并且服务器return获得成功结果
- 如果没有应用服务器事务,服务器returns 新值,然后客户端使用来自服务器的更新值再次调用处理函数,直到成功
- 当最终成功,并且发生不可恢复的错误,或者事务被中止(通过 returning undefined from the processing function)然后调用成功方法并返回结果。
因此,要使这项工作正常进行,显然您不能在第一个 returned 值上中止交易。
实现相同结果的一种变通方法——尽管它是耦合的并且不如仅使用设计的事务那样高效或合适——是将事务包装在 once('value', ...)
回调中,这将确保在 运行 交易之前将其缓存在本地。
我有交易问题。事务中的数据始终为空,更新处理程序仅被调用一次。 documentation 表示:
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
现在我知道现在没有其他客户端访问该位置。其次,如果我正确阅读了文档,如果无法检索和更新数据,应该多次调用 updateCounters 函数。
另一件事 - 如果我取出条件 if (counters === null)
执行将失败,因为计数器是 null
但在随后的尝试中事务完成正常 - 检索数据并进行更新。
简单 once - set
在这个位置工作得很好,但不安全。
请问我错过了什么?
这是代码
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);
这里是位置
中的数据counters:{
comments: 1,
alerts: 3,
...
}
通过在您的 if( ... === null )
块中 returning undefined
,您将中止交易。因此它永远不会向服务器发送尝试,永远不会意识到本地缓存的值与远程不同,并且永远不会使用更新后的值(来自服务器的实际值)重试。
committed
是 false
并且您的成功函数中的错误是 null
这一事实证实了这一点,如果交易被中止,就会发生这种情况。
交易工作如下:
- 将本地缓存值传递给处理函数,如果您从未从服务器获取此数据,则本地缓存值是
null
(该路径最可能的远程值) - 从处理函数中获取 return 值,如果该值是
undefined
则中止事务,否则,创建当前值(null)的散列并传递该值和新值(return由处理函数编辑)到服务器 - 如果本地散列与服务器的当前散列匹配,则应用更改并且服务器return获得成功结果
- 如果没有应用服务器事务,服务器returns 新值,然后客户端使用来自服务器的更新值再次调用处理函数,直到成功
- 当最终成功,并且发生不可恢复的错误,或者事务被中止(通过 returning undefined from the processing function)然后调用成功方法并返回结果。
因此,要使这项工作正常进行,显然您不能在第一个 returned 值上中止交易。
实现相同结果的一种变通方法——尽管它是耦合的并且不如仅使用设计的事务那样高效或合适——是将事务包装在 once('value', ...)
回调中,这将确保在 运行 交易之前将其缓存在本地。