我发现事务(https://www.firebase.com/docs/transactions.html)是处理并发的一种很酷的方式,但似乎它们只能从客户端完成。
我们使用Firebase的方式主要是从我们的服务器写入数据并在客户端上观察它们。有没有办法在通过REST API编写数据时实现乐观并发模型?
谢谢!
答案 0 :(得分:14)
您可以使用更新计数器使写操作以与事务类似的方式工作。 (我将在下面使用一些伪代码;对不起,但我不想写一个完整的REST API作为示例。)
例如,如果我有这样的对象:
{
total: 100,
update_counter: 0
}
这样的写规则:
{
".write": "newData.hasChild('update_counter')",
"update_counter": {
".validate": "newData.val() === data.val()+1"
}
}
我现在可以通过简单地在每次操作中传入update_counter来防止并发修改。例如:
var url = 'https://<INSTANCE>.firebaseio.com/path/to/data.json';
addToTotal(url, 25, function(data) {
console.log('new total is '+data.total);
});
function addToTotal(url, amount, next) {
getCurrentValue(url, function(in) {
var data = { total: in.total+amount, update_counter: in.update_counter+1 };
setCurrentValue(ref, data, next, addToTotal.bind(null, ref, amount, next));
});
}
function getCurrentValue(url, next) {
// var data = (results of GET request to the URL)
next( data );
}
function setCurrentValue(url, data, next, retryMethod) {
// set the data with a PUT request to the URL
// if the PUT fails with 403 (permission denied) then
// we assume there was a concurrent edit and we need
// to try our pseudo-transaction again
// we have to make some assumptions that permission_denied does not
// occur for any other reasons, so we might want some extra checking, fallbacks,
// or a max number of retries here
// var statusCode = (server's response code to PUT request)
if( statusCode === 403 ) {
retryMethod();
}
else {
next(data);
}
}
答案 1 :(得分:4)
答案 2 :(得分:2)
查看Firebase-Transactions项目:https://github.com/vacuumlabs/firebase-transactions
我相信,这对你的情况来说可能非常方便,特别是如果你从服务器上做了大量的写作。
(免责声明:我是其中一位作者)