使用 r2dbc 和 jOOQ 时事务回滚似乎不起作用
演示存储库
suspend fun insert(id: String) {
if (id == "b") {
throw RuntimeException("error while inserting")
}
db.insertInto(DEMO_TABLE)
.set(DEMO_TABLE.ID, id)
.awaitSingle()
}
演示服务
suspend fun addRecords(): Unit = transactionalOperator.executeAndAwait {
log.info("Inserting records")
repo.insert("a")
repo.insert("b") // throws error
}
然后
repo.getAll() // returns ["a"] instead of []
完整代码:https://github.com/linktosriram/r2dbc-jooq-rollback
尽管插入是在事务内完成的,但抛出异常时似乎不会回滚
日志:
Executing query: BEGIN READ WRITE
Executing query: insert into demo_table (id) values ($1)
Executing query: ROLLBACK
Executing query: select demo_table.id from demo_table
将 jOOQ
DSLContext
交换为 DatabaseClient
时,回滚有效。看起来像是 jOOQ 中的一个错误🤔
suspend fun insert(id: String) {
if (id == "b") {
throw RuntimeException("error while inserting")
}
dbClient.sql("insert into demo_table (id) values ('$id')")
.fetch()
.awaitSingle()
}
目前 Spring Boot 还没有官方的 R2dbc/jOOQ 集成。 Spring Boot 中的 jOOQ Stater 仅支持 Jdbc。
在我的项目中,我们使用 tx 感知连接工厂来创建
DSLContext
bean。
@Bean
DSLContext dslContext(ConnectionFactory connectionFactory) {
return DSL.using(
new TransactionAwareConnectionFactoryProxy(connectionFactory),
SQLDialect.POSTGRES
);
}
检查我的示例项目:https://github.com/hantsy/spring-r2dbc-sample/tree/master/jooq
但不幸的是,jOOQ 的很多功能,比如数据类型、转换器等,它们无法与 Spring Data R2dbc 交互。
在我们的项目中,我们使用 jOOQ 来执行复杂的查询(读取操作),但对于所有突变(插入、更新、删除),我们仍然使用 Spring Data R2dbc,因此我们优雅地避免了 tx 问题。