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

启用Hibernate批处理后并发更新出现HHH100503日志的原因排查

问题解析:HHH100503日志在并发乐观锁重试场景下频繁出现的原因

日志出现的核心原因

当启用Hibernate批处理后,并发请求触发乐观锁冲突并触发Spring Retry时,HHH100503: On release of batch it still contained JDBC statements日志的出现逻辑如下:

  • 开启批处理后,Hibernate会将SQL语句暂存到批处理缓冲区,直到达到batch_size阈值或事务提交时才批量执行。
  • 并发更新同一个带@Version的实体时,先提交的请求会成功更新版本号,后续请求的乐观锁校验失败,抛出ObjectOptimisticLockingFailureException并触发Spring Retry重试。此时当前事务回滚,但批处理缓冲区里的更新语句还未执行,会残留其中。
  • 当重试前的会话被释放时,Hibernate检测到批处理缓冲区还有未执行的语句,就会打出这条INFO日志。

为什么是INFO级别?

Hibernate将这条日志设为INFO级别,是因为它认为这是预期的可观测行为而非错误:

  • 这种情况可能是正常场景(比如事务回滚导致批处理未执行),也可能是代码问题(比如未正确触发批处理执行)。Hibernate无法自动区分场景,所以用INFO级别提示开发者“这里有未执行的批处理语句,请留意”,而非直接判定为错误。

这是不是Hibernate的bug?

不算bug,这是当前批处理机制的正常表现。
Hibernate的批处理缓冲区清理逻辑绑定在会话生命周期内,当乐观锁冲突导致事务回滚时,缓冲区的残留语句会在会话释放时被检测到,从而触发日志。虽然在重试场景下这条日志会频繁出现,显得冗余,但本质符合Hibernate的设计逻辑——它只是如实报告批处理的状态。

应对建议

  1. 调整日志级别:如果这条日志干扰排查,可以将org.hibernate.engine.jdbc.batch.internal.BatchingBatch的日志级别调高到WARN,这样就不会看到INFO级别的这条日志。比如在Logback配置中添加:
    <logger name="org.hibernate.engine.jdbc.batch.internal.BatchingBatch" level="WARN" />
    
  2. 无需担心数据一致性:你已经通过@Version乐观锁和Spring Retry保证了最终数据的正确性,这条日志只是状态提示,不会影响业务逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 02:53:11