首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GAE交易失败与幂等性

GAE交易失败与幂等性
EN

Stack Overflow用户
提问于 2013-07-18 11:13:50
回答 3查看 1.3K关注 0票数 10

Google文档包含以下段落:

注意:如果应用程序在提交事务时收到异常,并不总是意味着事务失败。在事务已提交并最终将成功应用的情况下,您可以接收DatastoreTimeoutException、ConcurrentModificationException或DatastoreFailureException异常。只要有可能,就让Datastore事务幂等,这样如果您重复一个事务,最终结果将是相同的。

等等,什么?似乎有一种非常重要的事务不能被幂等,因为它们依赖于当前的数据存储状态。例如,一个简单的计数器,如在一个相似的按钮中。事务需要读取当前计数,增加它,然后再次写出计数。如果事务看起来“失败”,但并没有真正失败,而且我无法在客户端告诉它,那么我需要再试一次,这将导致一次单击生成两个“喜欢”。当然有办法用GAE来防止这种情况吗?

编辑:

这似乎是分布式系统中固有的问题,就像Guido van Rossum以外的非其他系统一样--参见这个链接:

app引擎数据存储事务异常

因此,如果您想要获得高度的可靠性,那么设计幂等事务几乎是必须的。

我想知道是否有可能在整个应用程序中实现一个全球系统,以确保幂等性。关键是在数据存储中维护事务日志。客户端将生成一个GUID,然后将该GUID包含在请求中(相同的GUID将在对同一个请求进行重试时重新发送)。在服务器上,在每个事务开始时,它会在数据存储中查找带有该ID的事务实体组中的一个记录。如果它找到了它,那么这是一个重复的事务,因此它将返回而不执行任何操作。

当然,这需要启用跨组事务,或者将单独的事务日志作为每个实体组的子事务。如果失败的实体键查找速度慢,也会影响性能,因为几乎每个事务都会包含失败的查找,因为大多数GUID都是新的。

至于额外的数据存储交互的额外$成本,这可能仍然低于我必须使每个事务幂等的情况,因为这将需要在每个级别上检查数据存储中的内容。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-22 01:27:04

题名/责任者: et .在app引擎的本地(每个实体组)事务基础上设计了一个彻底的全局事务系统。在较高的层次上,它使用了与您描述的GUID类似的技术。丹处理“潜水艇写作”(交易,你描述的报告失败,但后来表面的成功,以及许多其他理论和实践细节的数据存储。erick在木薯中实现了dan的设计。

我不一定建议你实现他的设计或使用木薯,但你肯定会对这项研究感兴趣。

在回答您的问题时:很多人使用GAE应用程序,这些应用程序使用数据存储而没有幂等性。只有当您需要某些类型的担保(如您所描述的担保)时,这才是重要的。当你确实需要它们的时候,了解它们绝对是很重要的,但是你通常不需要。

该数据存储是在超级存储的基础上实现的,在深度在本文中中进行了描述。简而言之,它在每个实体组中使用多版本并发控制帕克斯进行跨数据中心的复制,这两种方法都有助于潜艇写入。我不知道是否有公共号码的潜艇写入频率在数据存储,但如果有,搜索使用这些术语和数据存储邮件列表应该找到他们。

亚马逊的S3实际上不是一个可比的系统,它更像是一个CDN,而不是一个分布式数据库。亚马逊的SimpleDB可以与之媲美。它最初只提供最终一致性,最终添加了一种非常有限的事务,他们称之为条件写入,但它没有真正的事务。其他NoSQL数据库(redis、mongo、couchdb等)在事务和一致性方面有不同的变化。

基本上,分布式数据库总是在规模、事务宽度和一致性保证的强度之间进行权衡。埃里克·布鲁尔( eric )的盖定理最熟悉这一点,它说,权衡的三个轴心是一致性、可用性和分区容忍度。

票数 7
EN

Stack Overflow用户

发布于 2014-05-01 21:05:31

我想出的使计数器幂等的最好方法是使用集合而不是整数来计数。因此,当一个人“喜欢”某样东西时,而不是增加一个计数器,我会在下面这样的东西中添加类似的内容:

代码语言:javascript
复制
class Thing {
Set<User> likes = ....

public void like (User u) {
  likes.add(u);
}
public Integer getLikeCount() {
  return likes.size();
}
}

这是在java,但我希望您理解我的观点,即使您正在使用python。

此方法是幂等的,您可以为您喜欢的次数添加一个用户,它只会被计算一次。当然,它的代价是存储一个巨大的集合而不是一个简单的计数器。但是,嘿,你不需要记录下你的喜好了吗?如果您不想使Thing对象膨胀,请创建另一个对象ThingLikes,并在Thing对象上缓存类似的计数。

票数 1
EN

Stack Overflow用户

发布于 2014-02-26 20:50:54

另一个值得研究的选项是应用程序引擎内置的跨组交易支持,它允许您在单个数据存储事务中对多达五个实体组进行操作。

如果您更喜欢在堆栈溢出上阅读,这个问题有更多详细信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17721895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档