我發現交易(https://www.firebase.com/docs/transactions.html)是處理併發的一種很酷的方式,但它似乎只能從客戶端完成。通過REST API的Firebase交易
我們使用Firebase的方式主要是通過從我們的服務器寫入數據並在客戶端觀察它們。通過REST API編寫數據時,是否有辦法實現樂觀併發模型?
謝謝!
我發現交易(https://www.firebase.com/docs/transactions.html)是處理併發的一種很酷的方式,但它似乎只能從客戶端完成。通過REST API的Firebase交易
我們使用Firebase的方式主要是通過從我們的服務器寫入數據並在客戶端觀察它們。通過REST API編寫數據時,是否有辦法實現樂觀併發模型?
謝謝!
您可以利用更新計數器使寫操作以類似於事務的方式工作。 (我將在下面使用一些僞代碼;對不起,但我不想寫出完整的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);
}
}
這看起來很不可思議,非常感謝!我會盡力實施它,並讓你知道是否有麻煩。 –
適用於更新對象。是否有可能實施類似的東西刪除? –
@MartinŠťáva我認爲這並不是真的有可能,因爲你不用DELETE傳遞數據。我不認爲大多數系統都在意這一點,因爲他們假設如果你說DELETE,你確實是指DELETE,並且不關心那裏的內容,只要你引用了正確的鍵/ URL。 –
退房火力地堡,交易項目:https://github.com/vacuumlabs/firebase-transactions
我相信,這可能是你的情況很方便,特別是如果你做了很多從服務器寫入的。
(免責聲明:我是作者之一)
嗨馬丁,你如何設想工作?請記住,事務依賴於來回的討論,客戶端一直在嘗試設置數據,服務器不斷迴應併發的更改,最終他們決定付出價值或放棄。 – Kato
嗨加藤,當然,我試圖實現完全相同的討論服務器端。我可以通過GET請求獲取firebase中對象的當前狀態,然後通過PUT更改它,但是有沒有辦法讓我知道該對象是否已被修改? –
我不這麼認爲;這是通過REST嘗試事務的麻煩的一部分。我想我們可以將一個能夠輕鬆模擬交易的解決方案放在一起。讓我回答一個問題。 – Kato