1

总结 我有一个问题,数据库从我的任务队列中写入(大约 60 个任务,以 10/s 的速度)在并发数据库读取期间以某种方式被覆盖/丢弃相同的数据。我将解释它是如何工作的。任务队列中的每个任务都为模型的特定数据存储实体分配一个唯一 ID。如果我在模型上运行索引数据存储查询并在任务队列正在进行时遍历实体,我希望某些实体将被任务队列操作(即..分配一个 ID)和其他实体尚未生效。不幸的是,似乎正在发生的事情是在查询循环期间,已经操作过的实体(即..成功分配了一个 ID)被覆盖或丢弃,说它们从未被操作过,即使 - 根据我的日志- 他们进行了手术。

为什么会这样?我需要能够在不影响后台任务队列写入操作的情况下读取我的数据状态。我想这可能是一个缓存问题,所以我尝试在查询中强制执行 use_cache=False 和 use_memcache=False ,但这并没有解决问题。任何帮助,将不胜感激。

其他有趣的注意事项:如果我在执行数据存储查询之前 允许任务队列完全完成,然后执行数据存储查询,它会按预期运行,并且不会覆盖/丢弃任何内容。

4

1 回答 1

1

这通常表明对实体的写操作不在事务中执行。事务可以检测到这样的并发写入(和读取!)操作并重试它们,确保数据保持一致。

您还需要注意查询(如果它们不是祖先查询)最终是一致的,这意味着它们的结果有点“落后于”实际的数据存储信息(从数据存储信息更新到相应的索引需要一些时间)查询使用会相应更新)。因此,在处理查询结果中的实体时,您还应该以事务方式验证它们的内容。就我个人而言,我更喜欢进行keys_only 查询,然后通过键查找获取实体,这始终是一致的(当然,如果我打算更新实体,也可以在事务中,如果需要,在读取时)。

例如,如果您查询没有唯一 ID 的实体,您可能会得到实际上最近操作过并具有 ID 的实体。所以你应该(事务性地)检查实体是否真的有一个 ID 并跳过它的更新。

还要确保您没有更新从投影查询中获得的实体 - 从此类查询中获得的结果可能不代表整个实体,将它们写回将消除投影中未包含的属性。

于 2019-10-19T04:50:42.660 回答