Description
Description
In the V5 documentation on transactions, it states that When mongock.transactionEnabled is true, it enforces native transactions, throwing an exception if the driver is not capable of it.
. Regarding Spring boot ecosystems, it additionally mentions that in the Springboot ecosystems, the transactions manager needs to be injected in the context.
The transaction configuration section of the MongoDB Spring Data Driver page never explicitly mentions configuring a MongoTransactionManager
bean to be available in the Spring context, which may be a documentation error. Though it can be inferred from the various worked examples, for example this one for Spring Data V4.
The issue I've encountered is that the connectionDriver
method of SpringDataMongoV4ContextBase.java
has an autowired dependency to PlatformTransactionManager
. This method parameter is used in conjunction with the Mongock config to determine if the driver should enable transactions:
txManagerOpt.filter(tx -> config.getTransactionEnabled().orElse(true)).ifPresent(tx -> driver.enableTransaction());
However, this instance of PlatformTransactionManager
is not necessarily a MongoTransactionManager
. For example, in one of my projects that also has JDBC configured, Springboot automatically wires a JdbcTransactionManager
bean. The connectionDriver
method had the JdbcTransactionManager
bean autowired and used this to determine if transactions should be enabled, irrespective of the fact that a JdbcTransactionManager
could not be used for Mongo transactions. This led to some initial confusion, as the project had not made a MongoTransactionManager
bean available to the Spring context, and we were unsure why Mongock was not falling over.
This is further compounded by the fact that this autowired PlatformTransactionManager
bean is not used for the Mongo transactions in SpringDataMongoV4DriverBase.java
- the method specificInitialization
explicitly creates a new instance of MongoTransactionManager
.
So it would appear that the current logic in Mongock v5 for Spring Data is that a PlatformTransactionManager
of any concrete implementation (not necessarily a Mongo implementation) must be available in the Spring context for transactions to be enabled. However this transaction manager will not be used for Mongo transactions, instead deferring to an insta
608C
nce manually instantiated by Mongock.
Summary of the two issues:
connectionDriver
method inSpringDataMongoV4ContextBase
does not ensure thePlatformTransactionManager
bean is applicable to MongoDB- Mongock is not using the
MongoTransactionManager
available in the Spring context for transactions of ChangeUnits
The second issue could be considered a non-issue if SpringDataMongoV4ContextBase
does not use autowired PlatformTransactionManager
beans, thus deferring enabling transactions solely to the Mongock config. Documentation would need to be updated to explicitly state that Mongock uses its own instance of MongoTransactionManager
, not the Spring context instance.
PRIORITY
Normal (since there isn't a severe impact to usage)
Version and environment
Mongock
- Mongock version: 5.4.0
- Modules involved: mongock-springboot-v3, mongodb-springdata-v4-driver
- How Mongock is used: annotation approach (via @EnableMongock and application.yml)
Environment
- Framework and libraries versions. Especially those that affect directly to Mongock(Spring, Spring data, MongoDB driver, etc.): Spring Boot 3.2.3, spring-boot-starter-data-mongodb 3.2.3 (Spring Data MongoDB 4.2.3, MongoDB driver 4.11.1), spring-boot-starter-jdbc 3.2.3 (Spring JDBC 6.1.4)
- Infrastructure: Kubernetes, Docker, SO, etc.: N/A (issue occurring locally)
Steps to Reproduce
- Create a Spring Boot app - either manually create a
JdbcTransactionManager
bean, or defer to the Spring autoconfiguration inDataSourceTransactionManagerAutoConfiguration
. Do not create aMongoTransactionManager
bean - Set
mongock.transaction-enabled: true
- Configure Spring Boot app against a MongoDB database with transactions enabled (i.e. replica set)
- Write a simple migration within the
@Execution
method block
Behaviour
Expected behavior: [What you expect to happen]
Either
- Mongock errors due to no
MongoTransactionManager
bean being available; OR - Mongock is successful but does not use a
PlatformTransactionManager
bean to determine if the driver enables transactions
Actual behavior: [What actually happens]
- Mongock is successful, but uses a non-Mongo transaction manager for the purposes of checking whether the driver should enable transactions
How often the bug happens: [What percentage of the time does it reproduce?]
Always