我试图通过在 dslContext.transactionResult 中使用反应方式在 Postgresql 上设置局部变量。 我想在触发器的帮助下在产品历史表中保留 user_id,即更改产品表的用户的 ID。
我的产品历史表触发函数在其中使用这个脚本来获取 user_id 变量。
DECLARE user_id text := current_setting('user_id', true);
实际上我想通过使用 jooq 反应式事务支持来创建与此 sql 脚本相同的行为。
BEGIN;
SET LOCAL user_id = 'XXXXXXXXX';
insert into .....
COMMIT;
但是下面的 jooq 代码不起作用,user_id 变量没有在产品历史表中获取它的值。
public Mono<Product> upsertProduct(Long productId, String name, String userId) {
return dslContext.transactionResult(configuration -> {
DSLContext ctx = DSL.using(configuration);
return Mono.from(ctx.setLocal(DSL.name("user_id"), DSL.value(userId)))
.flatMap(result -> Mono.from(ctx.insertInto(PRODUCT)
.set(PRODUCT.ID, productId)
.set(PRODUCT.NAME, name)
.onConflictOnConstraint(Keys.PRODUCT_PK)
.doUpdate()
.set(PRODUCT.NAME, name)
.returning())
.map(dbRecord -> dbRecord.into(Product.class)));
});
}
我预计它应该在产品历史表中设置局部变量 user_id,同时将产品记录保存到产品表中。但它没有设置局部变量,所以即使它将产品记录保存到产品表中,我也看不到产品历史表中的 user_id 字段。
请问一下setLocal的reactive是否支持?因为当我尝试通过使用 dslContext.transaction 来使用非反应性方式时..它有效并且我可以在产品历史表上看到局部变量。
3.16.5
x86_64-pc-linux-musl 上的 PostgreSQL 11.18,由 gcc 编译(Alpine 12.2.1_git20220924-r4)12.2.1 20220924,64 位
17
macOS Big Sur [版本 11.6]
org.postgresql:postgresql:42.3.6
Result::getRowsUpdated
的 R2DBC 规范,不返回任何更新计数的查询根本不返回任何内容:
返回对数据库的查询更新的行数。如果查询没有更新任何行,则可能为空。
Statement::executeUpdate
总是返回一个 int
值,例如0
,就算一无所获
Statement::execute
在流模式下使用 JDBC 时,它也不会为语句批处理中的每个语句返回更新计数,以防您发送多个 ;
分隔的语句到服务器,例如在 MySQL 或 SQL Server 中。
现在,jOOQ 没有做任何特别的事情。它只是在这里继承了 R2DBC 的行为。如果 R2DBC
Statement
没有产生任何结果,那么 jOOQ 的 RowCountQuery
也不能
您查询中的问题是您正在使用
flatMap()
:
Mono.from(ctx.setLocal(DSL.name("user_id"), DSL.value(userId)))
.flatMap(result -> Mono.from(ctx.insertInto(PRODUCT) // ...
但是第一个查询不会产生任何结果,所以您的
flatMap()
lambda 永远不会被调用!你应该做的是使用then()
:
Mono.from(ctx.setLocal(DSL.name("user_id"), DSL.value(userId)))
.then(Mono.from(ctx.insertInto(PRODUCT) // ...