首页 > 解决方案 > AsyncIOMotorCommandCursor.fetch_next 是否会阻止可重试读取?

问题描述

我正在尝试在 Mongo Atlas 集群故障转移期间诊断电机读取故障。Retryable-Reads 规范定义aggregate调用是可重试的,但Cursor.getMore不是。我的代码如下所示:

cursor = db.foo.aggregate([...])

if not await cursor.fetch_next:
    raise SomeException

doc = cursor.next_object()

此代码似乎不会在集群故障转移期间重试,因为它在内部调用getMore 我假设。我不完全清楚是否是这种情况。更不用说fetch_next无论如何都已弃用

将其更改为可重试读取?

async for doc in cursor:
    break
else:
    raise SomeException

还是这会导致相同的内部处理,而问题出在其他地方?

目标是尝试以可重试的方式从聚合管道(有一个或没有)读取单个结果文档,如果没有则引发异常。

标签: pythonmongodbpymongomongodb-atlas

解决方案


您需要挽救驱动程序在此代码之外的网络错误引发的任何异常,并在这种情况下重复整个迭代。

驱动程序会自动重试初始查询,但不会重试 getMores,因为它们无法指定结果集中的位置。因此,驱动程序的可重试读取逻辑对于健壮的应用程序来说是不够的,您仍然需要在完整迭代的级别上处理应用程序中读取错误的可能性。

如果您正在检索单个文档,它通常应该包含在初始查询响应中,并且不需要 getMores,因此实际上这个问题不适用。


推荐阅读