Java大批量全量同步需分页拉取+分批写入,禁用OFFSET,采用游标分页与批量插入;目标端用DROP+RENAME原子切换;配限流、索引优化、一致性校验及监控告警。

Java 中大批量数据全量同步不能靠“一次查完、一次插入”硬扛,必须拆解为可控制、可恢复、低干扰的流程。核心是平衡一致性、性能和业务可用性——尤其当数据达百万级以上时,清空再灌入的操作本身就有风险,必须配套幂等、分片、断点、资源管控等机制。
分页拉取 + 分批写入
避免单次查询加载全部数据导致 OOM 或数据库连接超时。按主键或时间字段分页(推荐基于自增 ID 或时间戳的游标分页,而非 OFFSET),每次拉取 5 万~20 万条,用 MyBatis 的 foreach 批量插入,配合事务控制粒度(如每 1 万条 commit 一次)。
- 分页 SQL 示例:
SELECT * FROM t_contract WHERE id > ? ORDER BY id LIMIT 10000 - 禁用
OFFSET:大数据量下LIMIT 100000, 10000效率急剧下降 - 写入失败时,记录当前最大 ID,下次从该位置续跑,实现断点续传
目标端安全清空策略
全量同步前需清理旧数据,但直接 TRUNCATE 会锁表且不可回滚,高并发场景下更危险。建议:
- 使用 DROP TABLE + RENAME 方案:先同步到新表(如
t_contract_new),校验无误后原子切换:RENAME TABLE t_contract TO t_contract_bak, t_contract_new TO t_contract - 若必须原表更新,改用 DELETE WHERE 分批次删除(如每次删 5 万条 + sleep 100ms),避免长事务和锁升级
- 切换前后做行数比对和关键字段抽样校验,确保数据完整性
资源与稳定性保障
全量过程对 CPU、内存、网络、数据库连接池都是压力测试。需主动限流和隔离:
立即学习“Java免费学习笔记(深入)”;
- 线程池独立配置:不复用业务线程池,核心线程数建议 ≤ 数据库连接池大小,避免连接耗尽
- JVM 参数调优:增大堆外内存(
-XX:MaxDirectMemorySize),适配批量 IO;关闭 GC 日志暂停(-XX:+UseG1GC -XX:MaxGCPauseMillis=200) - 加开关控制:通过配置中心动态开启/暂停同步任务,便于异常时快速止损
- 同步期间关闭非必要索引:写入完成后重建,大幅提升插入速度(注意唯一索引仍需保留以防重复)
一致性兜底与监控
全量同步不是“做完就完”,而是要闭环验证:
- 源端与目标端执行
COUNT(*)和SUM(CRC32(字段))对比,快速识别整体偏差 - 记录同步起止时间、总条数、成功/失败数、耗时,上报至 Prometheus + Grafana
- 失败重试最多 3 次,超过则告警并人工介入;失败明细写入日志+DB 表,支持定位
- 搭配增量同步作为补偿:全量完成后立即触发一次增量拉取,覆盖全量窗口期的变更


















