【发布时间】:2016-09-02 01:52:31
【问题描述】:
注意:我问了一个与 previously 非常相似的问题,但对我正在寻找的内容不够清楚,并且过于激进地标记了答案。我正在寻找关于特定点的确认是/否。
我想构建一个自动化作业,通过按计划查询 DocumentDb 来对 DocumentDb 文档执行离线处理,查找自上次执行检查后发生更改的文档。
鉴于 DocumentDb 中可用的元数据,执行此操作的方法如下:
- 进程首次运行时,检索所有文档。
- 将结果集中的最大 _ts 值存储为 highWatermark,以及将该特定值作为其 _ts 值的文档的 ID 和 eTag。
- 对于每个后续查询,包括“WHERE _ts >= highWatermark”子句。过滤掉之前记录的 eTag 没有改变的文档。结果是自上次运行查询以来所有更改的集合。
我的问题是这能保证工作吗?保证这不会遗漏任何文件吗?据我所知,它归结为 DocumentDb 实现中 _ts 周围的事务语义,没有详细记录。我想知道是否可以保证没有文档可以使用 lower 的 _ts 值进行更新集合中的文档。
编辑,由大卫的评论提示:
更准确地说,有几个特定的场景:
- 如果两个文档 D0 和 D1 的更新在 T0 和 T1(其中 T1 > T0,这样任意查询可能返回 D0 而不是 D1)应用到数据库,D0._ts > D1 是否可能._ts?使用 strict-greater-than 是有意的,因为我提议的实现处理接收相同 _ts 但只有其中一些更新被查询检索到的多个更新。
- 假设我在时间 T0 执行了实现的查询,并且查询需要很长时间才能运行,和/或需要几次 ExecuteNextAsync() 调用才能从服务器中提取多个批次。在此期间,更新了 2 个不同的文档(D1 和 D2),获得 T1 和 T2 的 _ts 值(其中 T1
【问题讨论】:
-
假设您有大量文档要处理。您为 _ts 设置了高水位标记,但在处理过程中,先前处理的文档之一被另一个进程更新,因此具有比您的高水位标记更新的时间戳。这不会是您在未来的处理过程中错过文档更新的边缘情况吗?
-
@DavidMakogon,我已经为我的问题添加了一些精确性。您的场景代表了我要弄清楚的部分内容-如果在返回查询结果的过程中更新了文档 D,则 D._ts 是否可能严格小于结果集中的最大 _ts?您可以在 SQL Server 中使用 rowversion 获得此类保证,因为 rowversion 值保证在提交时单调增加,但由于 _ts 基于挂钟时间戳,我不知道在这些情况下它的保证是什么。跨度>
标签: azure azure-cosmosdb