我想将数据扇出到 4 个不同的节点。由于firebase事务过程可能会失败,确保所有4个数据都被保存的正确方法是什么?
假设我有 4 个保存数据的函数,每个函数都会调用一个事务。
编辑:
function saveToFirstNode(data, response) {
/*
* @param
* [response] is a callback function
* that indicates whether the save was successful
*/
firebase.database().ref('cars/' + data.carId)
.transaction(function(currentData) {
currentData.distance += data.distance;
return currentData;
}, function(error, commited, snapshot) {
if (error) {
response(false);
} else if (commited) {
response(true)
}
}, false);
}
function saveToSecondNode(data, response) {...}
function saveToThirdNode(data, response) {...}
function saveToFourthNode(data, response) {...}
1.使用第一种方法
这种方法使用嵌套的回调函数,并在每次保存成功时调用 progress()。
缺点是,如果其中一个保存过程失败,它将重新保存从第一个到第四个的所有数据。
var queue = new Queue(ref, options, function(data, progress, resolve, reject) {
saveToFirstNode(data, function(success) {
if (success) {
progress(25);
saveToSecondNode(data, function(success) {
if (success) {
progress(50);
saveToThirdNode(data, function(success) {
if (success) {
progress(75);
saveToFourthNode(data, function(success) {
if(success) {
resolve(data);
} else {
reject();
}
});
} else {
reject();
}
});
} else {
reject();
}
});
} else {
reject();
}
});
});
2.使用第二种方法
这种方法保证所有数据都将被保存。当保存过程失败时,它将从失败的规范重试,而不是从第一个到第四个。但是您认为仅进行4次保存就大材小用了吗?这是正确的方法吗?
在队列/规格中定义规格:
{
"save_to_first_node": {
"in_progress_state": "save_to_first_node_in_progress",
"finished_state": "save_to_first_node_finished"
},
"save_to_second_node": {
"start_state": "save_to_first_node_finished",
"in_progress_state": "save_to_second_node_in_progress",
"finished_state": "save_to_second_node_finished"
},
"save_to_third_node": {
"start_state": "save_to_second_node_finished",
"in_progress_state": "save_to_third_node_in_progress",
"finished_state": "save_to_third_node_finished"
},
"save_to_fourth_node": {
"start_state": "save_to_third_node_finished",
"in_progress_state": "save_to_fourth_node_in_progress"
}
}
队列代码:
var saveToFirstNodeOptions = {'specId': 'save_to_first_node'};
var saveToFirstNodeQueue = new Queue(ref, saveToFirstNodeOptions, function(data, progress, resolve, reject) {
saveToFirstNode(data, function(success) {
if (success) resolve(data);
else reject();
});
});
var saveToSecondNodeOptions = {'specId': 'save_to_second_node'};
var saveToSecondNodeQueue = new Queue(ref, saveToSecondNodeOptions, function(data, progress, resolve, reject) {
saveToSecondNode(data, function(success) {
if (success) resolve(data);
else reject();
});
});
var saveToThirdNodeOptions = {'specId': 'save_to_third_node'};
var saveToThirdNodeQueue = new Queue(ref, saveToThirdNodeOptions, function(data, progress, resolve, reject) {
saveToThirdNode(data, function(success) {
if (success) resolve(data);
else reject();
});
});
var saveToFourthNodeOptions = {'specId': 'save_to_fourth_node'};
var saveToFourthNodeQueue = new Queue(ref, saveToFourthNodeOptions, function(data, progress, resolve, reject) {
saveToFourthNode(data, function(success) {
if (success) resolve(data);
else reject();
});
});
哪种方法是正确的?这个问题不是偏好,因为这两者是完全不同的方法,对性能和有效性都产生巨大影响。