Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine GAE事务失败与幂等性_Google App Engine_Transactions_Google Cloud Datastore - Fatal编程技术网

Google app engine GAE事务失败与幂等性

Google app engine GAE事务失败与幂等性,google-app-engine,transactions,google-cloud-datastore,Google App Engine,Transactions,Google Cloud Datastore,Google App Engine文档包含以下段落: 注意:如果您的应用程序在提交 事务,它并不总是意味着事务失败。你 可以接收DatastoreTimeoutException, ConcurrentModificationException或DatastoreFailureException 已提交事务的情况下的例外情况,以及 最终将成功应用。只要有可能,尽你所能 数据存储事务幂等,因此如果重复一个事务, 最终结果将是一样的 等等,什么?似乎有一类非常重要的事务不能简单地变为幂等,因为它们依

Google App Engine文档包含以下段落:

注意:如果您的应用程序在提交 事务,它并不总是意味着事务失败。你 可以接收DatastoreTimeoutException, ConcurrentModificationException或DatastoreFailureException 已提交事务的情况下的例外情况,以及 最终将成功应用。只要有可能,尽你所能 数据存储事务幂等,因此如果重复一个事务, 最终结果将是一样的

等等,什么?似乎有一类非常重要的事务不能简单地变为幂等,因为它们依赖于当前的数据存储状态。例如,一个简单的计数器,如在一个like按钮中。事务需要读取当前计数,增加它,然后再次写出计数。如果交易看起来“失败”,但实际上并没有失败,而且在客户端我无法判断这一点,那么我需要重试,这将导致一次单击生成两个“喜欢”。当然有一些方法可以防止GAE出现这种情况吗

编辑:

这似乎是分布式系统中固有的问题,正如Guido van Rossum之外的非其他人所说——请参见以下链接:

因此,如果您想要高度的可靠性,设计幂等事务似乎是非常必要的

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

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


就额外数据存储交互的额外$cost而言,这可能仍然比我必须使每个事务幂等的情况下要少,因为这将需要大量检查每个级别的数据存储中的内容。

dan wilkerson,simon goldsmith,et al.在app engine的本地(每个实体组)事务。在较高级别上,它使用了与您描述的GUID类似的技术。dan处理了“潜艇写入”,即您描述的报告失败但后来显示为成功的事务,以及数据存储的许多其他理论和实践细节。erick armbrust在中实现了dan的设计

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

回答你的问题:很多人实现的GAE应用程序使用数据存储时没有幂等性。只有当你需要像你描述的那样具有某种保证的事务时,这才很重要。了解你什么时候确实需要它们当然很重要,但你通常不需要

该数据存储是在megastore之上实现的,megastore有详细的描述。简言之,它在每个实体组内使用,并用于跨数据中心的复制,这两者都可能导致潜艇写入。我不知道数据存储中是否有潜艇写入频率的公共编号,但如果有,则使用这些术语进行搜索在数据存储的邮件列表中应该可以找到它们

amazon的S3实际上不是一个可比较的系统;它更像是一个CDN而不是一个分布式数据库。amazon的SimpleDB是可比较的。它最初只提供并最终添加了一种非常有限的事务,但它没有真正的事务。其他NoSQL数据库(redis、mongo、couchdb等)在事务和一致性方面有不同的变化


基本上,分布式数据库在规模、事务宽度和一致性保证强度之间总是存在权衡。eric brewer最为人所知,他说,权衡的三个轴是一致性、可用性和分区容差。

另一个值得研究的选项是app engine的内置支持t、 它允许您在单个数据存储事务中操作多达五个实体组


如果您更喜欢阅读堆栈溢出,则有更多详细信息。

我提出的使计数器幂等的最佳方法是使用集合而不是整数进行计数。因此,当一个人“喜欢”某个东西时,我会将类似的东西添加到如下内容中,而不是增加计数器:

class Thing {
Set<User> likes = ....

public void like (User u) {
  likes.add(u);
}
public Integer getLikeCount() {
  return likes.size();
}
}
类的东西{
集喜欢=。。。。
公共类空(用户u){
添加(u);
}
公共整数getLikeCount(){
return likes.size();
}
}
这是用java编写的,但我希望您能理解我的观点,即使您使用的是python


这个方法是幂等的,你可以添加一个用户多少次,它只会被计数一次。当然,它有存储一个庞大的集合而不是一个简单的计数器的惩罚。但是,嘿,你不需要跟踪喜欢吗?如果你不想让Thing对象膨胀,创建另一个ThingLikes对象,并缓存like count on the Thing object。

读一读Nick Johnson关于分布式事务的文章-这很有趣。我正试图思考如何将该技术应用到创建可靠计数器的任务中。如果只有一个用户可以访问计数器,这很容易:大概客户知道计数器的当前值,因此,只需将计数器的预期下一个值发送到D