Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Nothing needs to be done on the RabbitMQ side to use transactionsTransactions. The configuration and setup that’s required is all done within our ESR Microservices.

There are 3 basic requirements to enable RabbitMQ transactionsTransactions:

  1. call setChannelTransacted(true) on the RabbitTemplate Spring Bean.

  2. register a org.springframework.amqp.rabbit.transaction.RabbitTransactionManager Spring Bean.

  3. add the org.springframework.transaction.annotation.Transactional' annotations Annotations to the code which we want to wrap in a rabbit transaction.Rabbit Transaction

Transactions in MongoDB

Transactions are a relatively new feature of MongoDB (since v4.0)

https://docs.mongodb.com/manual/core/write-operations-atomicity/

  • To use MongoDB

...

  • Transactions - we have to have the MongoDB setup in ReplicSet mode AND we have to make configuration/setup changes with our ESR Microservices.
    NOTE: if we want to use MongoDB Transactions we must point to a MongoDB in ReplicaSet mode AND setup the code to use Transactions.

    • We cannot have the code to setup to use transactions and point to a MongoDB not in ReplicaSet (Transaction supporting) mode.

    • We cannot have the code setup without transaction support and point to a MongoDB in ReplicaSet (Transaction supporting) mode.

    • If we have the code setup with transaction support we must point to a MongoDB in ReplicaSet (Transaction supporting mode)

    • If the code is setup without transaction support we must point to a MongoDB not in ReplicSet (Transaction supporting mode)

In the code, there are 3 steps required to use MongoDB transactionsTransactions.

  1. register a org.springframework.data.mongo.MongoTransactionManager Spring Bean.

  2. add the org.springframework.transaction.annotation.Transactional' annotations to the code which we want to wrap in a MongoDB transactionTransaction.

  3. make sure any Mongo collections Collections (Collections are a similar to Tables in a typical RDBMS) you need to use within a transaction Transaction are created outside of the transaction 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 Collections are created as part of the installation Microservice Installation process.

The MongoTransactionManager works with inserts/updates to mongo through Spring Mongo Data repositories.

There are not a great number of examples showing how Spring works with MongoDB transactionsTransactions. The example here is a bit limited.
https://github.com/spring-projects/spring-data-examples/tree/master/mongodb/transactions

It relies on custom embeddedMongoDb for testing and seems to suggest you need to use mongoTemplate when updating doing inserts/updates to Mongo within a transactionTransaction. This is misleading - you can use Spring Data Mongo Repositories which are easier to use than mongoTemplates.

Global Transaction Manager

We want to link have linked the RabbitMQ and MongoDB transaction managers Transaction Managers so that they work together. To do this we create a parent/global transaction manager which delegates its commit/ & rollback calls to its child (mongo Mongo and rabbitRabbit) transaction managersTransaction Managers. We can use the built in Spring provided ChainedTransactionManager which can must have 1 or more child transaction managers ( You can’t use ChainedTransactionManager without any child transaction managers). The ChainedTransactionManager is registered as a Primary TransactionManager so Spring knows which of the Transaction Managers to use when there is more than 1.

We create a RabbitTransactionManager, if required, based on a boolean property app.transactions.rabbit.enabled having value ‘true’true.

We create a MongoTransactionManager, if required, based on a boolean propertyapp.transactions.mongo.enabled having value 'true’true.

If have at least 1 Rabbit or Mongo Transaction Manager, then we create a ‘parent' transaction manager.

...

Common Classes in the com.hee.tis.esr.common.transactions package, used to support Rabbit and Mongo transactions Transactions. The intention is that these common classes end up in a common shared library - so the code is only in once place.

#

Class Name

Description

1

ImportTransactionConfig

A Spring annotation Annotation used to pull in the transaction supportTransaction Support.

ESR Microservices wanting to pull in TransactionSupport should add ‘@ImportTransactionConfigthe @ImportTransactionConfig annotation to their Spring Boot Application “Application” class.

2

MongoCollectionInitializerConfig

Looks for Spring Data Mongo Repositories on startup and creates the required Collections in MongoDB if they don’t already exist.

3

NoopTransactionManager

Noop/Dummy Transaction Manager class. SeeTxConfigNoop

4

TxConfig

On application startup, logs the actual TransactionManager being used. This is just to help with debugging.

5

TxConfigGlobal

Creates a ChainedTransactionManager parent to wrap the Rabbit and/or Mongo Transaction Managers, if required. If created, this Spring Bean is named txManagerGlobal.

6

TxConfigMongo

Creates a MongoTransactionManager Spring Bean if the property app.transactions.mongo.enabled has value 'true’.

If created, this spring bean Spring Bean is named txManagerMongo

7

TxConfigNoop

Creates a Spring bean Bean using NoopTransactionManager if there is no bean Bean named txManagerGlobal. If created, this spring bean Spring Bean is named txManagerNoop

8

TxConfigRabbit

If the property app.transactions.rabbit.enabled has value 'true’ do the following:

  • Create the RabbitTransactionManager Spring Bean namedtxManagerRabbit

  • call setChannelTransacted(true) on the RabbitTemplate.

...