Quickperf @ExpectUpdate未识别Jooq配置的批量更新大小问题
batchUpdate和batched在Quickperf的@ExpectUpdate下表现不同? 这不是Quickperf的bug,核心原因是jOOQ两个批量更新API的设计逻辑存在差异,导致Quickperf的统计结果出现区别:
1. dslContext.batchUpdate(updatableRecords)的行为
batchUpdate会将所有传入的UpdatableRecord打包成单个JDBC批量请求,不受你配置的batch size影响。650条记录会被一次性放入一个JDBC Batch中,最终仅调用1次Statement.executeBatch()。
而Quickperf的@ExpectUpdate注解统计的是JDBC层面executeBatch()的调用次数,而非Batch内部包含的SQL语句数量,因此会显示实际执行1次UPDATE,BatchSize为650。
2. dslContext.batched()的行为
batched()是jOOQ专为分批批量操作设计的API,会严格遵循你配置的batch size=100:
- 内部自动将650条更新语句拆分,每攒够100条就触发一次
executeBatch() - 最终执行7次
executeBatch()(6次100条 + 1次50条)
这和你之前使用JDBC Template的批量更新行为完全一致,因此Quickperf能正确统计到7次UPDATE,测试通过。
解决方案
如果要继续用batchUpdate实现分批效果,需要手动将updatableRecords拆分成多个子列表,分多次调用batchUpdate:
// 手动拆分列表,每100条一批 List<List<UpdatableRecord>> batches = Lists.partition(updatableRecords, 100); batches.forEach(batch -> dslContext.batchUpdate(batch).execute());
更推荐直接使用batched()方法,它会自动处理分批逻辑,无需手动拆分。
补充说明
Quickperf通过拦截JDBC驱动的方法调用统计SQL执行次数,@ExpectUpdate计数的是批量执行的次数(即executeBatch()调用次数),而非批量中包含的单个SQL语句数。这也是JDBC Template的分批实现能被正确统计的原因——它本身就是分多次调用executeBatch()。
内容的提问来源于stack exchange,提问作者Eric van Coffee

