1

tl;dr How can I enable read preference SECONDARY on a single-operation read transaction, on a testing replica set?

I have created a MongoDB replica set from MongoDB deploy replica set for testing.

Then tried to make a simple, single-document transaction from MongoDB Transactions where I only change a few things such as read preference to secondary.

# 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

I get the following error

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

It works correctly if I change to read preference PRIMARY. If the read preference must be primary, it does not make any sense to have this option at all ...

What am I doing wrong or understanding incorrectly? This seems something so basic yet the documentation IMO does not explain this.

Am4teur
  • 125
  • 1
  • 9
  • What behavior do you expect with a secondary read in a transaction? – D. SM May 17 '21 at 14:36
  • I expect a normal read, i.e. I receive the data from the specific document. It can be a stale read, as long as is a valid read. I stopped looking into why the transaction does not allow me to read from secondary. I believe the problem may be from the collection. Not sure tho. – Am4teur May 17 '21 at 16:33

1 Answers1

0

Secondary reads in transactions do not make sense.

Transactions are running on the current primary. Hence, reads will be fulfilled by the primary. Requesting a secondary read is incompatible with transactions.

A secondary read may be fulfilled by any of the secondaries. The secondaries may have different data. This makes simple secondary reads non-repeatable, not causally consistent, etc.

If you want a simple secondary read, do not issue it under a transaction.

D. SM
  • 13,584
  • 3
  • 12
  • 21
  • Why is there an option readPreference with SECONDARY and PREFERED_SECONDARY on transactions then? it makes no sense to have this feature if it makes no sense to use it. You can even accomplish this (read from secondary) on the mongo shell using `rs.slaveOK()` command. – Am4teur May 17 '21 at 18:23
  • If you are asking about something that MongoDB driver or server documents, put the link to relevant documentation into the question. – D. SM May 17 '21 at 19:03
  • I have updated the question. tl;dr How can I enable read preference SECONDARY on a single-operation read transaction, on a testing replica set? Your response makes no sense to me, maybe you are right, I just need to understand why does this feature exist (feature: read preference secondary on a transaction) but cannot be used. – Am4teur May 17 '21 at 19:21
  • "read preference secondary on a transaction" is not a feature, as the error message says. I don't know why you think it is. – D. SM May 17 '21 at 21:23