【问题标题】:Querying for changed documents in DocumentDb在 DocumentDb 中查询更改的文档
【发布时间】:2016-09-02 01:52:31
【问题描述】:

注意:我问了一个与 previously 非常相似的问题,但对我正在寻找的内容不够清楚,并且过于激进地标记了答案。我正在寻找关于特定点的确认是/否。

我想构建一个自动化作业,通过按计划查询 DocumentDb 来对 DocumentDb 文档执行离线处理,查找自上次执行检查后发生更改的文档。

鉴于 DocumentDb 中可用的元数据,执行此操作的方法如下:

  • 进程首次运行时,检索所有文档。
  • 将结果集中的最大 _ts 值存储为 highWatermark,以及将该特定值作为其 _ts 值的文档的 ID 和 eTag。
  • 对于每个后续查询,包括“WHERE _ts >= highWatermark”子句。过滤掉之前记录的 eTag 没有改变的文档。结果是自上次运行查询以来所有更改的集合。

我的问题是这能保证工作吗?保证这不会遗漏任何文件吗?据我所知,它归结为 DocumentDb 实现中 _ts 周围的事务语义,没有详细记录。我想知道是否可以保证没有文档可以使用 lower 的 _ts 值进行更新集合中的文档。

编辑,由大卫的评论提示

更准确地说,有几个特定的​​场景:

  1. 如果两个文档 D0 和 D1 的更新在 T0 和 T1(其中 T1 > T0,这样任意查询可能返回 D0 而不是 D1)应用到数据库,D0._ts > D1 是否可能._ts?使用 strict-greater-than 是有意的,因为我提议的实现处理接收相同 _ts 但只有其中一些更新被查询检索到的多个更新。
  2. 假设我在时间 T0 执行了实现的查询,并且查询需要很长时间才能运行,和/或需要几次 ExecuteNextAsync() 调用才能从服务器中提取多个批次。在此期间,更新了 2 个不同的文档(D1 和 D2),获得 T1 和 T2 的 _ts 值(其中 T1

【问题讨论】:

  • 假设您有大量文档要处理。您为 _ts 设置了高水位标记,但在处理过程中,先前处理的文档之一被另一个进程更新,因此具有比您的高水位标记更新的时间戳。这不会是您在未来的处理过程中错过文档更新的边缘情况吗?
  • @DavidMakogon,我已经为我的问题添加了一些精确性。您的场景代表了我要弄清楚的部分内容-如果在返回查询结果的过程中更新了文档 D,则 D._ts 是否可能严格小于结果集中的最大 _ts?您可以在 SQL Server 中使用 rowversion 获得此类保证,因为 rowversion 值保证在提交时单调增加,但由于 _ts 基于挂钟时间戳,我不知道在这些情况下它的保证是什么。跨度>

标签: azure azure-cosmosdb


【解决方案1】:

使用默认一致性,这不能保证有效,因为具有较低 _ts 的文档可能会在以后出现。但是,如果您可以保证您的更新请求相距足够远(例如 60 秒),那么风险非常低。

只要您将每个具有更高 _ts 的文档都视为新文档,我认为 David 的边缘案例并不令人担忧。

您可能还想考虑使用类似 Richard Snodgrass 的时间模型的仅附加方法。这使得幂等语义更容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多