首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何选择正确的TransactionManager当使用R2DBC与天桥和JDBC时

如何选择正确的TransactionManager当使用R2DBC与天桥和JDBC时
EN

Stack Overflow用户
提问于 2022-10-24 15:00:16
回答 2查看 66关注 0票数 0

设置:

  • 微米3.7.2
  • micronaut data 3.8.1,micronaut-data-r2dbc,r2dbc-postgresql 0.9.2
  • 8.5.13,micronaut hikari,micronaut-flyway 5.4.1,postgresql 42.5.0
  • 测试容器(jdbc、r2dbc、postgresql) 1.17.5
  • io.micronaut.test.微核试验-资源3.6.2

测试配置(conf4k):

代码语言:javascript
复制
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:

为了使Flyway和micronaut数据使用相同的数据库和测试容器,两者的数据源需要命名相同。

问题:

由于同时使用JDBC和R2DBC,所以创建了同步和反应性TransactionManagers bean,当我使用@TransactionManagers时,我会得到以下错误:

代码语言:javascript
复制
Multiple possible bean candidates found: [io.micronaut.transaction.jdbc.DataSourceTransactionManager, io.micronaut.transaction.sync.SynchronousFromReactiveTransactionManager]

Thoughts:

我想,我可以用@TransactionalAdvice来解决这个问题,但是由于这两个数据源都需要相同的名称,所以这是不可能的。我试着用不同的名称命名数据源,但根本不起作用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-21 19:20:30

正如汉特西在他的文章中提到的,以编程方式使用R2dbcOperations#withTransaction()添加事务是一个临时的解决方案,直到Flyway最终支持R2DBC。请投这里

因为我使用了Kotlin和Coroutines,所以代码不是最优的,但对于一个希望是短暂的解决方案来说是可以的。要在Kotlin中使用它,必须用mono {}包装传递给withTransaction的函数体。

票数 0
EN

Stack Overflow用户

发布于 2022-11-12 12:51:56

您可以尝试将Jdbc (默认)和Flyway(Flyway依赖于Jdbc Datasouce)的数据源名称更改为另一个名称,然后在您的Jdbc存储库中使用@TransactionalAdvice来选择它。

在同一个项目中,我有一个使用Flyway和R2dbc的Micronaut示例。

但是我还没有尝试过@Transactional,对于事务处理,我使用的是R2dbcOperations.withTransaction,它工作得很好。

代码语言:javascript
复制
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()))
                                )
                )
        );
}

检查我这里的Micronaut R2dbc示例,希望它有帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74183112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档