您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Google App Engine中的竞争问题

Google App Engine中的竞争问题

是的,读写操作都可能发生争用。

事务开始后(在您的情况下,@ndb.transactional()调用注释的处理程序时),被访问的任何实体组(通过读或写操作无关紧要)都将立即标记为这样。那时还不知道在事务结束时是否会进行写操作- 甚至都没有关系。

太多的争用错误(不同于冲突错误!)表明太多的并行事务同时尝试访问同一实体组。即使没有事务实际尝试写入,它也可能发生!

开发服务器 模拟此争用,只有在使用实际数据存储区将其部署在GAE上时才能看到!

事务的自动重试可能会增加混乱,这可能在实际写入冲突或仅发生普通访问争用之后发生。这些重试在最终用户看来可能是某些代码路径的可疑重复执行-本例中的处理程序。

重试实际上会使情况变得更糟(短时间内)-向已经被大量访问的实体组抛出更多访问权限- 我已经看到这种模式的事务只有在指数退避延迟变得足够大以至于使事情降温后才起作用( (如果重试次数足够大)(允许已进行的交易完成)。

我的解决方法是将大部分事务性内容移入推送队列任务,在事务和任务级别禁用重试,而是完全重新排队任务-重试次数较少,但间隔更远。

通常,当您遇到此类问题时,您必须重新访问数据结构和/或访问它们的方式(您的交易)。除了保持强一致性(可能会非常昂贵)的解决方案外,您可能还需要重新检查一致性是否是必须的。在某些情况下,将其作为一揽子要求添加是因为看起来很简单。根据我的经验,它不是:)

另一件事可以帮助(但只有一点点)正在使用更快(也更昂贵)的实例类型- 较短的执行时间可以转化为较低的事务重叠风险。我注意到了这一点,因为我需要一个具有更多内存的实例,而这个实例碰巧也更快:)

Go 2022/1/1 18:45:16 有350人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶