bwaldvogel / mongo-java-server

Fake implementation of MongoDB in Java that speaks the wire protocol.
BSD 3-Clause "New" or "Revised" License
285 stars 88 forks source link

Support for Transactions #143

Open snava10 opened 4 years ago

snava10 commented 4 years ago

Mongdb recently introduced transactions which would be a great addition to the library. https://docs.mongodb.com/manual/core/transactions/ Transactions are only available on replica sets and need v6 or higher of the Wire Protocol as it relies on the OP_MSG.

38 and #71 are preconditions for this issue.

shahr commented 4 years ago

I'm working with Mongo 4.4 and attempting to write unit tests for some code which uses transactions - any chance this issue can be bumped up in priority?

I'm getting: com.mongodb.MongoClientException: Sessions are not supported by the MongoDB cluster to which this client is connected

bwaldvogel commented 3 years ago

I’m tempted to say that supporting transactions in mongo-java-server is something I consider out-of-scope.

After all I’m wondering if in over 99.9% of use cases the combination of MongoDB with transactions isn’t a bad decision anyway and using a good relational database such as PostgreSQL wouldn’t be the much better choice? In those (probably very rare) cases where MongoDB with transactions is a good idea, it’s probably better to run the tests against a real MongoDB, for example by using Testcontainers.

Please note that I would be very curious to learn about your use cases that justify the use of MongoDB with transactions! It might convince me that my old-school conservative view on NoSQL/relational databases is outdated ;)

shahr commented 3 years ago

I'm using multi document transactions where we persist data into the main collection and an audit collection to record changes. This audit log is then used (with change streams) as an event log to facilitate downstream processing. Transactions are useful here as in the event either the main collection or the audit collection fails to be updated, we can rollback the entire transaction and try again therefore preserving the event stream (audit log)

Hope this helps with the usecase.

I have implemented tests using the a real mongo instance using https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo for now, but I think for unit tests, it would be nice to still be able to use the in memory provider and then use a real mongo instance for integration tests. Let me know what you think.

bwaldvogel commented 3 years ago

@shahr: Thanks for the explanation of your use case. It’s a good example for why one would want to use transactions.

However, what I should have stressed a bit more: I’m not questioning transactions but rather the combination of MongoDB and transactions. In other words: Is there a good reason to use MongoDB instead of a relational database with very good support for transactions? If the collection is sharded, MongoDB will need to run a distributed transaction with at least "poor" performance. The use of such transactions is even questioned in the MongoDB transaction manual. If the performance doesn’t matter or there’s no sharding because the collection/database is not very large, then why using MongoDB in the first place?

shahr commented 3 years ago

@bwaldvogel yep, in general I do completely agree with you. The decision, however, to use MongoDB with transactions was due to the following:

Hope that helps with the context.

snava10 commented 3 years ago

@bwaldvogel In our case we have an application that needs to make changes to multiple collections in an atomic way, hence transactions. Our data model is complex and fits better in a document based database than in a relational one, and we also make extensive use of change streams, that's why we are going for mongo DB. If MJS is a reflection of MongoDB and the latter has transactions it makes sense for MJS to have it as well.