简体   繁体   English

将 R2DBC 与 Flyway 和 JDBC 一起使用时如何使用 select 正确的 TransactionManager

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

Setup:设置:

  • micronaut 3.7.2微航 3.7.2
  • micronaut-data 3.8.1, micronaut-data-r2dbc, r2dbc-postgresql 0.9.2 micronaut-data 3.8.1,micronaut-data-r2dbc,r2dbc-postgresql 0.9.2
  • Flyway 8.5.13, micronaut-jdbc-hikari, micronaut-flyway 5.4.1, postgresql 42.5.0 Flyway 8.5.13、micronaut-jdbc-hikari、micronaut-flyway 5.4.1、postgresql 42.5.0
  • testcontainers (jdbc, r2dbc, postgresql) 1.17.5测试容器(jdbc、r2dbc、postgresql)1.17.5
  • io.micronaut.test-resources 3.6.2 io.micronaut.test-resources 3.6.2

Test Configuration (conf4k):测试配置(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.为了使 Flyway 和 micronaut 数据使用相同的数据库和测试容器,两者的数据源需要命名相同。

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:由于同时使用 JDBC 和 R2DBC beeing,因此创建了同步和反应式 TransactionManagers bean,当我使用 @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.我想,我可以用@TransactionalAdvice 解决这个问题,但由于两个数据源需要具有相同的名称,所以这是不可能的。 I tried to name the datasources differently, but does not work at all.我试图以不同的方式命名数据源,但根本不起作用。

You can try to change the datasource name of Jdbc(default) and Flyway(Flyway depends on Jdbc Datasouce) to another name, then in your Jdbc Repository, use a @TransactionalAdvice to select it.你可以试试把Jdbc(default)和Flyway(Flyway depends on Jdbc Datasouce)的datasource name改成别的名字,然后在你的Jdbc Repository中,使用一个@TransactionalAdvice给select吧。

I have a Micronaut example using Flyway and R2dbc in the same project.我有一个在同一个项目中使用 Flyway 和 R2dbc 的 Micronaut 示例。

But I have not tried @Transactional , for the transaction handling, I was using R2dbcOperations.withTransaction , it works well.但是我没有尝试过@Transactional ,对于事务处理,我使用的是R2dbcOperations.withTransaction ,效果很好。

public Mono<Long> deleteAll() {
        var sql = "DELETE  FROM customers";
        return Mono.from(
                r2dbcOperations.withTransaction(status ->
                        Mono.just(status.getConnection())
                                .flatMap(connection -> Mono
                                        .from(connection.createStatement(sql).execute())
                                        .flatMap(result -> Mono.from(result.getRowsUpdated()))
                                )
                )
        );
}

Check my Micronaut R2dbc example here , hope it is helpful. 在此处查看我的 Micronaut R2dbc 示例,希望对您有所帮助。

As Hantsy mentioned in his post, adding transactions programmatically using R2dbcOperations#withTransaction() is a temporary workaround until Flyway finally supports R2DBC.正如Hantsy在他的帖子中提到的,在 Flyway 最终支持 R2DBC 之前,使用R2dbcOperations#withTransaction()以编程方式添加事务是一种临时解决方法。 Please upvote here .在这里投票。

Since I use Kotlin and Coroutines, the code is suboptimal but ok for a hopefully ephemeral solution.由于我使用 Kotlin 和 Coroutines,代码不是最理想的,但对于希望短暂的解决方案来说还可以。 To use that in Kotlin, one has to wrap the body of the function passed to withTransaction in mono {} .要在 Kotlin 中使用它,必须将传递给withTransaction的 function 的主体包装在 mono {}中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 r2dbc 的 @MappedEntity 注释中定义模式名称 - How to define schema name in @MappedEntity annotation for r2dbc Micronaut Data with R2DBC 是不是比经典的“每个连接一个线程”模型更具可扩展性的方法 Micronaut Data JDBC - Is Micronaut Data with R2DBC a more scalable approach than classical “one thread per connection” model Micronaut Data JDBC 使用带有 JDBC 的 micronaut-data 时如何获取 DB 序列值 - How to get DB sequence value when using micronaut-data with JDBC 使用@JdbcRepository 注解关联 JDBC 数据源名称 - Associate JDBC Datasource Name Using @JdbcRepository annotation 使用 MariaDB JDBC 客户端通过 AWS RDS 代理执行 IAM 身份验证 - Using MariaDB JDBC client to perform IAM authentification with AWS RDS Proxy 如何使用表和PostgreSQL JDBC驱动程序中的JSONB数据类型将JSON对象存储到PostgreSQL中 - How to store JSON object into PostgreSQL using JSONB data type inside table and PostgreSQL JDBC driver Micronaut:初始化 jdbc 连接时 MicronautTest 中的竞争条件 - Micronaut: Race condition in MicronautTest when initializing jdbc connection Flyway 更新两个数据库 - Flyway to update two databases 使用 Micronaut Data JDBC,如何转换 WHERE 子句的值? - With Micronaut Data JDBC, how do I transform a value for WHERE clauses? Micronaut 数据 JDBC 和 Postgres Arrays - Micronaut Data JDBC and Postgres Arrays
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM