【问题标题】:Google Datastore transaction exception谷歌数据存储交易异常
【发布时间】:2020-02-21 22:28:49
【问题描述】:

如 Google 数据存储文档中所述:

如果您的应用程序在提交事务时收到异常,并不总是意味着事务失败。在事务已提交的情况下,您可能会收到错误消息。

除了更新事务中的实体外,我还将推送任务添加到推送队列中。如果事务抛出了异常,但确实已经提交成功,这是否意味着推送队列任务入队成功?

【问题讨论】:

标签: google-cloud-datastore


【解决方案1】:

从 gso_gabriel 帖子中的引述来看,答案似乎是肯定的。

但是我有一些疑问。事务性任务入队似乎是数据存储客户端库(ndb/您的 java 库)的一个特性——我不记得看到它记录为通用数据存储(即服务器端)特性。

如果这是正确的,那么答案可能取决于实际的库实现。这就是我怀疑的地方——在某些情况下,客户端无法从异常本身确定事务是否成功提交。例如,请参阅app engine datastore transaction exception - 尽管答案还表明任务排队将在服务器端正确处理)。可能仍然可以使用附加逻辑确保正确的任务入队,但同样依赖于实现。

如果您想完全避免这种不确定性,我相信您有两种选择:

  • 如果即使在这些不利条件下正确及时地将任务入队很重要,您可以尝试使用task naming 作为使任务入队幂等的方法:即使异常无法指示任务是否已正确入队或不重试不会受到伤害,因为您不能(暂时)将命名任务入队两次。不过,您需要一种生成唯一任务名称的方法。

分配您自己的任务名称的一个优点是命名任务是 重复数据删除,这意味着您可以使用任务名称来保证 任务只添加一次。重复数据删除持续 9 天后 任务已完成或删除。

  • 如果执行任务的时间不是那么重要,则可以以不同的方式处理整个故事。例如,我已经有一些定期的更高级别的完整性检查作业来寻找孤立的项目(不管它们存在的原因)。在我的情况下,错过任务排队的影响只是产生这种孤儿实体的一种方式。由于时间并不重要,而且遇到此类事件的可能性很低,因此不必担心它们是可以接受的,保持简单并将恢复(重新尝试排队的任务)留给这些完整性检查作业。

【讨论】:

  • 时机对我的用例很重要,所以我可能会尝试使用命名任务来避免不确定性。根据您的经验,这种情况多久发生一次,即使写入成功,Datastore 也会引发异常?另外,使用命名任务时会增加多少估计延迟?
  • 就我个人而言,我没有明确地看到这方面的证据,但在大约几周内,我确实在我的应用程序中看到了几十个那些意想不到的孤儿。当时我没有找到很好的解释,所以我添加了完整性检查(这也可以保护我的应用程序中的错误)。有些是由于另一个罕见的问题 - 任务排队但未执行数小时。回想一下,有些可能与此有关——当时我没有密切注意例外情况,因为我得到了许多应有的争论。这是在 2016 年,当时我对我的应用程序进行了大量测试。从那以后就没有了,但也没有这么重的负担。
【解决方案2】:

如果事务确实成功 - 即使它遇到异常 - 推送队列任务也应该正确入队。

根据您提到的here 的文档,它说:

您可以将任务作为数据存储区事务的一部分加入队列,这样只有在事务成功提交的情况下,该任务才会加入队列并保证加入队列。添加到事务中的任务被视为事务的一部分,具有相同级别的隔离和一致性。

这意味着此推送将与交易的其余部分一起发生,使用与交易相同的功能和特性。这样,如果事务成功,您的任务应该会正确排队。

如果有信息请告诉我

【讨论】:

    猜你喜欢
    • 2019-01-15
    • 2014-06-26
    • 2018-09-05
    • 1970-01-01
    • 2019-02-06
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多