jooq 事务抢先一步 - 不能使用 'returningResult()'?

jooq transaction jumping the gun - cant use 'returningResult()'?

使用 JOOQ 3.11.11 / Java 11

正在创建一个事务以写入几个 tables。其中两个是相互作用的,因为我使用一个的 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),但最终结果(预期)是两个 tables 在 RuntimeException 之后都是空的。我看到的是第一个 table 有数据,但第二个没有。

跟进问题:

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

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
}