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 有数据,但第二个没有。
跟进问题:
- 我需要在每次插入后使用
.execute()
吗?
- 如果对整个过程进行处理,在后续插入中使用来自一个插入的推定 return 值是否有问题?
看起来您实际上并没有抛出异常:
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 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 有数据,但第二个没有。
跟进问题:
- 我需要在每次插入后使用
.execute()
吗? - 如果对整个过程进行处理,在后续插入中使用来自一个插入的推定 return 值是否有问题?
看起来您实际上并没有抛出异常:
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
}