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

H2 1.4.199 getGeneratedKeys返回其他事务ID或Future混叠问题求解

问题根因

  • H2 1.4.199版本存在原生BUG:该版本在复用数据库连接的场景下,getGeneratedKeys()有概率返回当前连接上一次插入操作生成的ID,而非当前执行语句的生成ID,若开启了H2的MVCC模式,触发概率会进一步提升。
  • 生成ID读取时序不合理:代码在事务提交前就读取生成的主键,此时H2的自增ID还未完成全局持久化,极端时序下会读取到未生效的ID值。
  • 冗余锁无实际作用:代码中对singleExecutor加的synchronized完全多余,ExecutorService的submit方法本身已经保证线程安全,额外加锁不会影响问题的触发,但会带来不必要的性能损耗。

解决方案

根治方案

直接将H2版本升级到1.4.200及以上稳定版,该版本已经官方修复了getGeneratedKeys()返回历史ID的问题,是成本最低的100%规避方案。

兜底兼容方案(无法升级H2时使用)

  1. 替换主键生成逻辑:不再依赖Statement.RETURN_GENERATED_KEYS获取数据库生成的ID,改为业务层手动生成全局唯一主键(如雪花ID)直接写入数据库,从根源上避免依赖数据库返回ID的风险。
  2. 调整ID读取时序:如果必须使用数据库生成主键,将getGeneratedKeys()的读取逻辑放到事务提交之后执行,确保读取到的是已经持久化的正式ID值。
  3. 调整H2配置:在连接参数中添加;MVCC=FALSE关闭MVCC模式,大幅降低BUG触发概率。
  4. 优化连接池配置:开启连接池的会话状态清理逻辑,每次从连接池获取连接时执行一次会话重置操作,避免连接复用带来的上下文残留问题。
  5. 增加业务校验:插入操作完成后新增校验步骤,拿着返回的ID查询数据库,确认对应记录存在且数据匹配,校验失败直接重试插入,从业务层面兜底避免ID重复的问题。

内容的提问来源于stack exchange,提问作者Andrew Snejovski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:36:07