Google App Engine 数据存储区,在更新几秒钟之前返回

2023-12-02

所以我需要在数据存储中更新值。我正在使用事务这样做,如下所示。提交更新后,我将结果发送回客户端,让他们知道更新已完成。然后,客户端发送另一个请求以获取更新的项目列表。据我所知,所有代码都正确执行,没有抛出任何错误,最终我确实得到了按预期显示的更新请求。

我的问题是,即使在提交之后,有时也需要几秒钟的时间才能在返回的列表中显示更新。如果只是延迟那就太糟糕了,但比这更糟糕。该列表在此时间段内返回不正确/未更新的值。我知道这种架构可能会出现延迟,但我认为交易的全部意义在于,如果像这样更新某些内容,那么一旦交易获取所需的项目,就不可能读取旧值了?事后很长一段时间看到旧值似乎是不正确的。更不用说等到事务表示它已提交并且具有整个 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 });
            }
        });
    });
});

您所体验到的称为“最终一致性”,它是 Cloud Datastore 架构的重要组成部分。如果没有它,数据存储对于所有请求都会慢得多。

请注意,所有get操作始终一致 - 只有查询受到影响,因为更新所有索引需要时间。索引更新可能需要几秒钟的时间。

有多种策略可以实现最终一致性,但它们在您的用例中并不真正适用/必要,因为更新的数据是已经可用到您的客户端应用程序。是您的客户端应用程序发起了保存请求。在几乎所有情况下,这意味着您可以避免重新加载数据。

例如,如果应用程序显示 17 条记录的列表,并且用户添加了一条新记录,则只需在后端响应保存请求后将新记录对象添加到显示的列表中即可。此类响应可能包括正在保存的记录中丢失的数据,例如它的数据存储 ID。在某些情况下,如果保存的对象具有许多已在服务器端更新的属性,则返回整个已保存对象可能会更容易。

在极少数情况下,当保存对象需要客户端加载一组全新的数据(其中可能包括更新的对象)时,客户端仍然可以用更新的对象替换查询中返回的对象 - 或者添加它(如果是)丢失的。同样,当查询结果到达时,您已经从“保存对象”响应中获得了完整更新的对象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Google App Engine 数据存储区,在更新几秒钟之前返回 的相关文章

随机推荐