Scille / umongo

sync/async MongoDB ODM, yes.
MIT License
447 stars 63 forks source link

Using mongodb session transaction #224

Closed dwisulfahnur closed 3 years ago

dwisulfahnur commented 4 years ago

Hello,

I want to use transaction based on Umongo document instance, could we use a custom session in the commit method?

The following is the way that I use on the motor without Umongo:

async with await db_client.start_session() as session:
    async with session.start_transaction():
        session.collection.insert_one({myobject:"objectvalue"})
talwrii commented 4 years ago

Just noting that in motor this transaction, as motor is referring to it, appears to be local to the process: https://github.com/mongodb/motor/blob/167e6a2497fe259d8bf9530cc7ad9e8da6f9fcac/synchro/__init__.py#L328. It will not protect you from changes to the underlying data in the other process.

Mongo does have the concept of multi-document trasnactions: https://www.mongodb.com/blog/post/mongodb-multi-document-acid-transactions-general-availability. This can be called from javascript, I'm unclear if any python library implements them.

lafrech commented 4 years ago

Mongo 4 introduces transactions. We use it in our application. To do so we had to override a lot of methods in pymongo driver to pass session through all methods. (About 300 LoC.)

We did it in a clumsy way. It could probably be achieved more elegantly. Perhaps using context variables.

I'm open to the idea. Just never got the time to do it correctly enough to merge it in umongo.

lafrech commented 4 years ago

Last time I checked, a while ago, the other ODMs I know (mongoengine and pymodm) didn't support transactions.

https://jira.mongodb.org/browse/PYMODM-100

lafrech commented 3 years ago

@dwisulfahnur @talwrii please see #315.

lafrech commented 3 years ago

@talwrii can you elaborate on your comment above about process-level transaction?

It is not clear to me in the docs.

https://motor.readthedocs.io/en/stable/api-tornado/motor_client.html#motor.motor_tornado.MotorClient.start_session

lafrech commented 3 years ago

315 addresses this by passing the session to all calls to underlying collection methods.

The good thing is that umongo only cares about the session. All the features provided by sessions are managed by the framework, along with their limitations (incl. MongoDB version compatibility issues).

AFAIU, this allows multidocument transactions on MongoDB 4.4 at least, as much as pymongo does.

lafrech commented 3 years ago

BTW, thanks @touilleMan for suggesting the use of context variables for this at PyConFR 2019.