Google App Engine 文档包含以下段落:
注意:如果您的应用程序在提交事务时收到异常,并不总是意味着事务失败。在事务已提交并最终将成功应用的情况下,您可能会收到 DatastoreTimeoutException、ConcurrentModificationException 或 DatastoreFailureException 异常。尽可能使您的数据存储事务具有幂等性,这样如果您重复事务,最终结果将是相同的。
等等,什么?似乎有一类非常重要的事务根本无法做到幂等,因为它们依赖于当前的数据存储状态。例如,一个简单的计数器,就像在一个赞按钮中一样。事务需要读取当前计数,增加它,然后再次写出计数。如果交易看起来“失败”但并没有真正失败,并且我无法在客户端告诉我,那么我需要再试一次,这将导致一键生成两个“喜欢”。肯定有一些方法可以通过 GAE 来防止这种情况发生吗?
编辑:
似乎这是分布式系统中固有的问题,除了 Guido van Rossum - 请参阅此链接:
因此,如果您想要高度的可靠性,看起来设计幂等事务几乎是必须的。
我想知道是否有可能在整个应用程序中实现一个全局系统以确保幂等性。关键是在数据存储中维护事务日志。客户端将生成一个 GUID,然后将该 GUID 包含在请求中(相同的 GUID 将在重试相同的请求时重新发送)。在服务器上,在每个事务开始时,它会在数据存储中查找具有该 ID 的事务实体组中的记录。如果它找到它,那么这是一个重复的事务,所以它会返回而不做任何事情。
当然,这需要启用跨组事务,或者将单独的事务日志作为每个实体组的子项。如果失败的实体键查找速度很慢,也会对性能造成影响,因为几乎每个事务都会包含失败的查找,因为大多数 GUID 都是新的。
就额外数据存储交互的额外成本而言,这可能仍然低于我必须使每个事务幂等的情况,因为这需要大量检查每个级别的数据存储中的内容。