jooq 交易开枪 - 不能使用'returningResult()'?

Posted

技术标签:

【中文标题】jooq 交易开枪 - 不能使用\'returningResult()\'?【英文标题】:jooq transaction jumping the gun - cant use 'returningResult()'?jooq 交易开枪 - 不能使用'returningResult()'? 【发布时间】:2021-12-27 23:57:24 【问题描述】:

使用 JOOQ 3.11.11 / Java 11

创建一个事务来写入几个表。其中两个是交互的,因为我使用一个中的 auto_inc 行 #s 作为另一个的 fk 列值。

DSLContext writeContext = DSL.using(sourceDestConnection.getDestination(), SQLDialect.POSTGRES_10);
writeContext.transaction(writeTransaction -> 
    try 
         ...

         Map returnMap = writeFn(dataToWrite, writeTransaction);
         secondWriteFn(moreDataToWrite, returnMap, writeTransaction);
         throw new RuntimeException();
     


// this fn should write a series of records and save the auto_increment field in a map
public void writeFn(...) 
    Map<Long, Long> idMap = new HashMap<>();
    DSLContext context = DSL.using(configuration);
    for (Record record : importBits) 
        Record result = context.insertInto(IMPORT_TABLE).set(record)
                .returningResult(ID_FIELD).fetchOne();
        idMap.put((Long) record.get(ID_FIELD_LOOKUP), (Long) result.get(ID_FIELD));
    
    return idMap;



// this fn should use the saved auto_inc fields from the previous fn as FK columns
public void secondWriteFn(...) throws IOException 
    DSLContext context = DSL.using(configuration);
    for (Map mergeMap : importTypes) 
        context.insertInto(MERGE_TYPE_TABLE)
                .set(buildMergeMap(mergeMap, idMap));
    


// this just builds a map to insert
public ImmutableMap<Object, Object> buildMergeMap(Map mergeMap, Map idMap) 
    return ImmutableMap.builder()
      .put(... columns ...)
      .put(foreignKeyColumn, idMap.get(fkLookup_from_first_write_fn))
      .build();

     

p 代码来自内存(不同的 PC),但最终结果(预期)将是两个表在 RuntimeException 之后都是空的。我看到的是第一个表有数据,但第二个没有。

跟进问题:

是否需要在每次插入后使用.execute()? 如果整个过程都被事务处理,那么在后续插入中使用来自一个插入的推定返回值是否有问题?

【问题讨论】:

不相关,我怀疑你可以通过编写批量插入语句来加快速度。关于您的问题,您的两个xyzWriteFn() 中的configuration 是什么?您的交易的实际主体是什么?你有一个try 块。你捕捉到你的异常,还是真的抛出它? Lo siento。 'configuration' 是传入的 'writeTransaction'。 那内心的尝试?这是在踢我吗? :facepalm(是的)。 如果你想把这个放在答案中,我很乐意接受。 【参考方案1】:

看起来您实际上并没有抛出异常:

writeContext.transaction(writeTransaction -> 

    // Try here!
    try 
        ...

        Map returnMap = writeFn(dataToWrite, writeTransaction);
        secondWriteFn(moreDataToWrite, returnMap, writeTransaction);
        throw new RuntimeException();
    

    // You omitted the catch, but if you catch the above RuntimeException, then
    // jOOQ does not know about it, and happily commit your transaction

【讨论】:

以上是关于jooq 交易开枪 - 不能使用'returningResult()'?的主要内容,如果未能解决你的问题,请参考以下文章

JOOQ & 交易

使用 scala 在 Jooq 中进行交易和条件更新

多个存储库上的 JOOQ @Transactional

jOOQ 是不是使用不同的连接来执行不同的查询?

JOOQ 插入记录列表

Jooq 生成视图类