jOOQ反应式transactionResult中setLocal无法设置PostgreSQL本地变量问题
问题:jOOQ反应式事务中setLocal设置PostgreSQL本地变量不生效
我尝试在jOOQ的dslContext.transactionResult中通过反应式方式为PostgreSQL设置本地变量,借助触发器将修改product表的用户ID(user_id)存入product history表。
触发器函数通过以下脚本获取user_id变量:
DECLARE user_id text := current_setting('user_id', true);
我希望通过jOOQ反应式事务复现如下SQL的行为:
BEGIN; SET LOCAL user_id = 'XXXXXXXXX'; insert into ..... COMMIT;
但以下jOOQ代码无法生效,product history表中无法获取到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))); }); }
预期保存product记录时,user_id本地变量会被设置并写入product history表,但实际仅成功保存product记录,user_id未被存入。非反应式的dslContext.transaction功能正常,product history表可以获取到user_id变量,请问jOOQ是否支持反应式setLocal?
环境信息
- jOOQ版本:3.16.5
- 数据库:PostgreSQL 11.18 on x86_64-pc-linux-musl,64位
- Java版本:17
- 操作系统:macOS Big Sur [Version 11.6]
- JDBC驱动:org.postgresql:postgresql:42.3.6
解决方案
jOOQ 3.16.x版本的反应式API中,setLocal方法存在上下文绑定问题,无法将本地变量正确关联到当前反应式事务的连接上,这就是非反应式事务正常但反应式场景失效的原因。可以通过以下两种方式解决:
直接执行SET LOCAL SQL语句替代setLocal方法
把ctx.setLocal(...)替换为直接执行原生SQL,确保变量设置在当前事务的连接上下文里:public Mono<Product> upsertProduct(Long productId, String name, String userId) { return dslContext.transactionResult(configuration -> { DSLContext ctx = DSL.using(configuration); return Mono.from(ctx.execute("SET LOCAL user_id = ?", 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))); }); }升级jOOQ版本到3.17及以上
jOOQ在3.17版本修复了反应式事务中setLocal的上下文绑定问题,升级后原代码的ctx.setLocal调用可以正常生效,无需修改逻辑。
内容的提问来源于stack exchange,提问作者Özlem Ulağ
相关产品推荐
相关产品推荐

