Sergei Podlipaev
Sergei Podlipaev

Reputation: 1421

Java Spring: Compatibility for both transactional and non-transactional versions of mongodb

I'm using Spring Boot 2.1.2 release (mongodb-driver v 3.8.2) and developing web application that operates with mongodb. My application is compatible with mongodb 3.4 version (This version doesn't support transactions) and now I'm introducing transactional mechanism. I annotate my service method with transactional annotation

@Transactional
    public void process(Object argument) {
        ...
        ...
        ...
    }

and it works fine for mongodb v 4, everything works just excpected - failed transactions are rolledback.

But when I start my app with mongodb v 3.4 my app crashes with

Sessions are not supported by the MongoDB cluster to which this client is connected

exception.

The problem is that I want my app to support both cases: transactional and non-transactional with the same code (for both mongodb versions). So I wonder how can I do it? It seems like my application should create session only for specific version of mongo, i.e. this annotation should be processed only for this case.

How can I do it?

Upvotes: 2

Views: 1726

Answers (2)

Sergei Podlipaev
Sergei Podlipaev

Reputation: 1421

I have found a solution. Spring checks for existence of PlatformTransactionManager in current context before creating a transaction. So if this bean is not defined, then session wouldn't be opened for transaction. Thus I had used on condition bean for this purpose in my configuration class:

    @Bean
    @Autowired
    @ConditionalOnExpression("'${mongo.transactions}'=='enabled'")
    MongoTransactionManager mongoTransactionManager(MongoDbFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }

So MongoTransactionManager bean will be created only if mongo.transactions parameter is set to enabled.

Upvotes: 4

Michiel
Michiel

Reputation: 3410

Not sure if it works, but you could try to move the @EnableTransactionManagement annotation to a new configuration class, add the annotations @Configuration and @Profile("enableTransactions") to the configuration class, and run the application using the given profile when you need the transaction management to be auto-configured, for instance using:

mvn spring-boot:run -Dspring-boot.run.profiles=enableTransactions

Upvotes: 2

Related Questions