...
call
setChannelTransacted(true)
on the RabbitTemplate Spring Bean.register a
org.springframework.amqp.rabbit.transaction.RabbitTransactionManager
Spring Beanadd the
org.springframework.transaction.annotation.Transactional
Annotations to the code which we want to wrap in a Rabbit Transaction. This Transactional Annotation works for both Mongo and Rabbit Transactions.
Transactions in MongoDB
Transactions are a relatively new feature of MongoDB (since v4.0)
...
register a
org.springframework.data.mongo.MongoTransactionManager
Spring Bean.add the
org.springframework.transaction.annotation.Transactional
annotations Annotations to the code which we want to wrap in a MongoDB Transaction. This Transactional Annotation works for both Mongo and Rabbit Transactions.make sure any Mongo Collections (Collections are a similar to Tables in a typical RDBMS) you need to use within a Transaction are created outside of the Transaction, in advance. When using Mongo Transactions - you can no longer create a collection ‘on demand’ within a transaction by simply inserting into it. To work around this there is a class
com.hee.tis.esr.common.transactions.MongoCollectionInitializerConfig
which looks for instances of Spring Data Repositories and creates any Mongo Collections required on application startup. This is a temporary solution until we are using something like mongobee to make sure Collections are created as part of the Microservice Installation process.
...
# | Class Name | Description |
---|---|---|
1 |
| A Spring Annotation used to pull in the Transaction Support. ESR Microservices wanting to pull in TransactionSupport should add the |
2 |
| Looks for Spring Data Mongo Repositories on startup and creates the required Collections in MongoDB if they don’t already exist. |
3 |
| Noop/Dummy Transaction Manager class. See |
4 |
| On application startup, logs the actual TransactionManager being used. This is just to help with debugging. |
5 |
| Creates a |
6 |
| Creates a MongoTransactionManager Spring Bean if the property If created, this Spring Bean is named |
7 |
| Creates a Spring Bean using |
8 |
| If the property
|
9 |
| Contains public constant values related to this package. Things like Spring Bean names and important property names. |
Testing Transaction Support
We have done some work to allow us to test Transactions that apply to both Rabbit and MongoDB using Test Containers. By using Test Containers we use actual instances of MongoDB and RabbitMQ run in Docker Containers in our tests - this is useful because we are using actual instances not ‘test’ instances which might behave different from the ‘real' thing.
The base code for testing transactions is within the following packages
com.hee.tis.esr.common.transactions.test
# | Class | Description |
---|---|---|
1 | ||
2 | ||
3 | ||
4 | ||
5 | ||
6 |
com.hee.tis.esr.common.autoconfigure
This package contains the class 'EmbeddedMongodbReplicaSetBootstrapConfiguration
'. This class it loaded via Spring AutoConfiguration because it’s referred to in the smallsrc/test/resources/META-INF/spring.factories
file.
Code Block |
---|
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.hee.tis.esr.common.autoconfigure.EmbeddedMongodbReplicaSetBootstrapConfiguration |
This class starts up MongoDB in a Test Container in ReplicaSet mode. It also sets the following properties which can them be used by the test code:
Code Block |
---|
embedded.mongodb.port
embedded.mongodb.host
embedded.mongodb.database
embedded.mongodb.replicaset |
We had to write custom code to setup MongoDB in a TestContainer in ReplicaSet mode so we can test transactions. Our custom code is based on the classcom.playtika.test.mongodb.EmbeddedMongodbBootstrapConfiguration
from the library “com.playtika.testcontainers:embedded-mongodb:1.32
“ - it starts MongoDB within a Test Container but it’s not in ReplicaSet mode.