spring-projects / spring-data-mongodb

Provides support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-mongodb/
Apache License 2.0
1.62k stars 1.09k forks source link

Introduce AbstractRoutingMongoDatabaseFactory #3636

Open pelletier197 opened 3 years ago

pelletier197 commented 3 years ago

Hello maintainers!

I am currently using Spring Data MongoDB in a multi-tenant environment. To give a little context, as a security requirement from our customers, we need to have a different credential set for every tenant, which forces us to have multiple instances of MongoClient.

We managed to make this work by overriding the method doGetMongoDatabase from SimpleMongoClientDatabaseFactory, which I believe the way people usually do it. However, we're facing a really big issue with this way of doing thing: since we have multi instances of MongoClient, using @Transactional doesn't work properly. We end up with this error

java.lang.IllegalStateException: state should be: ClientSession from same MongoClient

Would you happen to have a fix for that? Or is it in your roadmap to offer an official support for multi-tenancy?

Thank you for your help!

mp911de commented 3 years ago

Right now, we don't fully support multi-tenancy within transactions because although the factory implementation is overridden, we partially bind different resources to the actual transaction and so the ClientSession doesn't match the transactionally bound MongoClient.

We discussed implementing a routing variant of MongoDatabaseFactory to support future implementations and want to ensure that transactional usage works for multi-tenancy.

pelletier197 commented 3 years ago

Thank you for your answer.

How long could we expect to wait for a support of this? And would you happen to have an idea of workaround in the meantime?

mp911de commented 3 years ago

Since this never was a priority this ticket has to line up in the queue. For now, the workaround would be to not use @Transactional infrastructure but rather make use of the programmatic ClientSession API on MongoTemplate.withSession(…) where you control the session lifecycle.

divyajnu08 commented 3 years ago

Hi Mark

Could you please explain the requirement in detail ? Multiple clients will access a single datasource. How we will handle transactions ? What is meant by routing here ?

Thanks

pelletier197 commented 3 years ago

Could you please explain the requirement in detail ? Multiple clients will access a single datasource.

For this part, I need to be able to run transactions on different MongoClient. Each client targets a different database, with a different credential set. And each database contains the same collections, but the documents insinde those collections are specific to the tenant.

Hope this helps!

mp911de commented 3 years ago

@divyajnu08 you might also want to have a look at https://github.com/spring-projects/spring-data-cassandra/tree/main/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/session/lookup that contains a Cassandra variant.