You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus中Jdbi批量查询大ID列表遇Arjuna事务异常求助

解决Quarkus+Jdbi批量IN查询的Arjuna事务异常

异常原因分析

你的代码在循环执行多批次查询时,若外层存在@Transactional注解,所有查询会共享同一个长事务。当批次过多、总查询耗时超过Arjuna事务超时阈值时,事务会被收割器强制终止,导致数据库连接被回收,结果集提前关闭,触发result set is closed错误。若尝试复用同一个Handle执行多次查询,同样会绑定到同一事务上下文,面临相同的超时问题。

解决方案

1. 让每个批次查询使用独立短事务

移除外层事务(或调整事务传播行为),利用Jdbi的withHandle自动管理单次查询的事务生命周期,确保每个批次查询完成后立即提交事务,避免长事务超时。

修正后的代码示例:

List<Map<String, Object>> result = new ArrayList<>();
// DB2的IN子句最多支持1000个参数,可将批次调至1000以减少循环次数
List<List<Integer>> listOfIdLists = chopListToLists(ids, 1000);

for (List<Integer> idBatch : listOfIdLists) {
    // 每次查询独立开启/提交事务,结果集立即加载到内存
    List<Map<String, Object>> batchResult = jdbi(db).withHandle(handle -> 
        handle.createQuery("SELECT ... WHERE id IN (<id>)")
              .bindList("id", idBatch)
              .mapToMap()
              .list() // 立即将结果集转为内存列表,避免事务关闭后依赖结果集
    );
    result.addAll(batchResult);
}

2. 调整事务传播行为(若必须保留外层事务)

如果方法外层必须存在事务,将事务传播行为设为REQUIRES_NEW,让每个批次查询在独立的新事务中执行:

import jakarta.transaction.Transactional;

@Transactional(Transactional.TxType.REQUIRES_NEW)
public List<Map<String, Object>> fetchBatch(List<Integer> idBatch) {
    return jdbi(db).withHandle(handle -> 
        handle.createQuery("SELECT ... WHERE id IN (<id>)")
              .bindList("id", idBatch)
              .mapToMap()
              .list()
    );
}

// 调用处
List<Map<String, Object>> result = new ArrayList<>();
List<List<Integer>> listOfIdLists = chopListToLists(ids, 1000);
for (List<Integer> batch : listOfIdLists) {
    result.addAll(fetchBatch(batch));
}

3. 临时调整事务超时时间(不推荐)

若无法拆分事务,可临时增大Quarkus事务超时阈值,在application.properties中添加:

quarkus.transaction-manager.default-timeout=60s

此方案仅适用于查询总耗时可控的场景,长期来看仍建议拆分短事务。

关键注意事项

  • 确认DB2的IN子句参数上限:DB2默认允许IN子句最多包含1000个参数,批次大小不要超过这个值,否则会触发SQL语法错误。
  • 确保结果集立即加载:Jdbi的list()方法默认会立即将结果集转为内存列表,避免依赖未关闭的结果集;若使用stream()则需注意在事务内处理完流。

内容的提问来源于stack exchange,提问作者jon martin solaas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 04:30:47