测试副本集上带有 ReadPreference Secondary 的事务上的 MongoDB 错误

问题描述

tl;dr 如何在测试副本集上的单操作读取事务上启用读取首选项 SECONDARY?

我从 MongoDB deploy replica set for testing 创建了一个 MongoDB 副本集。

然后尝试从 MongoDB Transactions 进行简单的单文档事务,其中我只将读取偏好更改为次要等几项。

# Step 1: Define the callback that specifies the sequence of operations to perform inside the transactions.
def callback(session):
    collection_one = session.client.mydb1.foo
    # Important:: You must pass the session to the operations.
    collection_one.find_one({'id': 0},session=session)

# Step 2: Start a client session.
with client.start_session() as session:
    # Step 3: Use with_transaction to start a transaction,execute the callback,and commit (or abort on error).
    session.with_transaction(
        callback,read_concern=ReadConcern('snapshot'),# <- changed from 'local' to 'snapshot'
        write_concern=wc_majority,read_preference=ReadPreference.SECONDARY) # <- changed from PRIMARY to SECONDARY

我收到以下错误

...
pymongo.errors.InvalidOperation: read preference in a transaction must be primary,not: Secondary(tag_sets=None,max_staleness=-1,hedge=None)

如果我更改为读取首选项 PRIMARY,它可以正常工作。 如果阅读偏好必须是主要的,那么这个选项根本没有任何意义......

我做错了什么或理解有误?这看起来很基本,但 IMO 的文档并没有解释这一点。

解决方法

事务中的二次读取没有意义。

事务正在当前主节点上运行。因此,读取将由主要完成。请求二次读取与事务不兼容。

二级读取可以由任何二级完成。次级可能有不同的数据。这使得简单的二级读取不可重复、因果不一致等。

如果您想要简单的二次读取,请不要在事务下发出。