Skip to content

Transaction fails when multiple database aliases use different MongoDB clients #2908

@contrail-ray

Description

@contrail-ray

When configuring multiple database connections with different host parameters, an InvalidOperation error is raised when executing a transaction that spans multiple models bound to different database aliases.

class DocDefault(Document):
    id = StringField(primary_key=True)

    meta = {
        'db_alias': 'default'
    }


class DocAdmin(Document):
    id = StringField(primary_key=True)

    meta = {
        'db_alias': 'admin'
    }

if __name__ == '__main__':
    # This configuration works correctly
    right_config = [
        {
            'db': 'default',
            'alias': 'default'
        },
        {
            'db': 'admin',
            'alias': 'admin'
        },
    ]

    # This configuration triggers the error
    wrong_config = [
        {
            'db': 'default',
            'alias': 'default',
            'host': 'mongodb://127.0.0.1:27017/default',
        },
        {
            'db': 'admin',
            'alias': 'admin',
            'host': 'mongodb://127.0.0.1:27017/admin',
        },
    ]

    for c in wrong_config:
        connect(**c)

    with run_in_transaction():
        doc_default = DocDefault(id='a')
        doc_default.save()

        doc_admin = DocAdmin(id='a')
        doc_admin.save()
        print(doc_default)
        print(doc_admin)

The following exception is raised:

pymongo.errors.InvalidOperation: Can only use session with the MongoClient that started it

With wrong_config, two distinct MongoClient instances are created because the host parameters differ.
The transaction context currently manages a single session stack and does not differentiate between database aliases.
Consequently, models bound to the admin alias incorrectly inherit the session belonging to the default alias's client, leading to the InvalidOperation error.
With right_config, the same MongoClient is reused (since only db and alias are provided), so the error does not occur.

Would it make sense to consider managing transactions on a per-database-alias basis? I'm not entirely sure if this is the most appropriate solution, but perhaps differentiating sessions by alias could help ensure that the correct MongoClient and session are used for each operation. Curious to hear if there might be a better approach or if I'm misunderstanding the intended behavior. Thanks for taking a look!

(My English is not very good, so I used AI assistance for this translation. I apologize for any mistakes or awkward phrasing.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions