micronautr2dbcmicronaut-datar2dbc-postgresqlmicronaut-test

How to select the correct TransactionManager when using R2DBC together with Flyway and JDBC


Setup:

Test Configuration (conf4k):

datasources {
    default {
        dialect=POSTGRES
        options {
            currentSchema=default
        }
    }
}
r2dbc {
    datasources {
        default {
            dialect=POSTGRES
            options {
                currentSchema=default
            }
        }
    }
}
flyway {
    datasources {
        default {
            enabled=true
            locations="classpath:databasemigrations"
            schemas=["default"]
            create-schemas=true
        }
    }
}
test-resources {
  containers {
    postgres {
      image-name="postgres:12.12"
      hostnames=["localhost"]
    }
  }
}

Preconditions:

To make Flyway and micronaut data use the same database and testcontainer, the datasource of both needs to be named alike.

Problem:

Because of JDBC and R2DBC beeing used at the same time, synchronous and reactive TransactionManagers beans are created and I get the following error, when I use @Transactional:

Multiple possible bean candidates found: [io.micronaut.transaction.jdbc.DataSourceTransactionManager, io.micronaut.transaction.sync.SynchronousFromReactiveTransactionManager]

Thoughts:

I thought, I could solve that with @TransactionalAdvice, but since both datasources need to have the same name, this is not possible. I tried to name the datasources differently, but does not work at all.


Solution

  • As Hantsy mentioned in his post, adding transactions programmatically using R2dbcOperations#withTransaction() is a temporary workaround until Flyway finally supports R2DBC. Please upvote here.

    Since I use Kotlin and Coroutines, the code is suboptimal but ok for a hopefully ephemeral solution. To use that in Kotlin, one has to wrap the body of the function passed to withTransaction in mono {}.