所以我需要在数据存储区中更新我需要的值。我正在使用交易,如下所示。提交更新后,我将结果发送回客户端,让他们知道更新已经完成。然后,客户端发送另一个请求以获取更新的项目列表。据我所知,所有代码都正确执行,没有抛出错误,最终我确实按要求显示请求的更新。
我的问题是甚至在提交之后有时在返回列表中显示更新之前有时几秒钟。如果它只是一个蹩脚的延迟,但它比那更糟糕。该列表在此时间段内返回不正确/未更新的值。我知道这个架构可能存在延迟,但我认为事务的整个过程是这样的,如果事情像这样更新,一旦事务抓住了所需的项目,没有什么可能读取旧值?在很长一段时间后看到旧值似乎不正确。更不用说等到事务发生后表示它已经提交并且有一个完整的300ms + RTT并且在它被认为承诺之后仍然会在几秒钟内获得坏值。我在这里缺少什么?
/*
We don't actually delete a post, we simply replace it with a [removed]
version of itself.
*/
router.delete('/', function (req, res) {
//Check our parameters
if (req.body == null || req.body["Thread"] == null || typeof req.body["Thread"] !== "string") {
res.json({ success: false, message: "Thread name was not included as a parameter.", data: null});
return;
}
if (req.body == null || req.body["PostNumber"] == null) {
res.json({ success: false, message: "Post Number was not included as a parameter.", data: null });
return;
}
if ((parseInt(req.body["PostNumber"]) || 0) < 1) {
res.json({ success: false, message: "Post Number was not a valid numeric value.", data: null });
return;
}
var transaction = datastore.transaction();
transaction.get(datastore.key(['Post', PostName(req.body["Thread"], 6, parseInt(req.body["PostNumber"]))]), function (err, value) {
if (err)
{
res.json({ success: false, message: "Transaction failed.", data: null });
return;
}
if (value === null)
{
res.json({ success: false, message: "Post and thread combination does not exist.", data: null });
return;
}
value.data.CreatorName = "[removed]";
value.data.CreatorFooter = "";
value.data.Contents = "[removed]";
transaction.save(value);
transaction.commit(function (err) {
if (err)
{
res.json({ success: false, message: "Transaction failed.", data: null });
}
else
{
res.json({ success: true, message: "Erased post information from table", data: null });
}
});
});
});
答案 0 :(得分:3)
您所体验的内容称为&#34;最终的一致性&#34;,它是Cloud Datastore架构的重要组成部分。没有它,数据存储区对于所有请求都会慢得多。
请注意,所有get
操作始终保持一致 - 只有查询受到影响,因为更新所有索引需要时间。索引更新可能需要几秒钟。
有几种策略可以使用最终的一致性,但它们在您的用例中并不是真正适用/必要的,因为更新的数据已经可用到您的客户端应用程序。是您的客户端应用程序启动了保存请求。在几乎所有情况下,这意味着您可以避免重新加载数据。
例如,如果应用程序显示17条记录的列表,并且用户添加了新记录,则只需在后端响应保存请求后将新记录对象添加到显示的列表中。这样的响应可以包括从保存的记录中丢失的数据,例如,它的数据存储区ID。在某些情况下,如果它有许多已在服务器端更新的属性,则返回整个已保存对象可能更容易。
在极少数情况下,当保存对象需要客户端加载一组全新的数据(可能包括更新的对象)时,客户端仍然可以用更新的对象替换查询中返回的对象 - 或者添加它如果它丢失了同样,到查询结果到达时,您已经拥有了一个完整的更新对象来自&#34;保存对象&#34;响应。