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

Spring集成JDBCLockRepository选主时重复插入DB致键冲突的原因咨询

关于Spring Integration JDBC锁机制重复键冲突的设计疑问

几年前,我们在MariaDB集群上将自研主节点选举机制切换为Spring Integration主节点选举机制,二者均依赖唯一键冲突实现。切换的原因是原机制在MariaDB集群同步时偶尔会出现死锁问题。

切换时我们的理解是:仅主节点会向INT_LOCK表写入带时间戳的锁记录,其他节点仅通过读取该表判断是否需要重新选主(当主节点宕机时,锁的时间戳会过期)。

但最近版本更新后,日志中频繁出现重复键冲突告警。分析代码后发现,所有节点一直在尝试插入同一行数据。相关核心逻辑如下(来自DefaultLockRepository的acquire方法):

if (this.template.update(this.updateQuery, new Object[]{this.id, epochMillis(), this.region, lock, this.id, this.ttlEpochMillis()}) > 0) {
    return true;
} else {
    try {
        return this.template.update(this.insertQuery, new Object[]{this.region, lock, this.id, epochMillis()}) > 0;
    } catch (DataIntegrityViolationException var4) {
        return false;
    }
}

逻辑分析:

  • 第一个updateQuery的WHERE条件只有当前持有锁的主节点能满足,因此非主节点执行update后返回0,会进入else分支
  • 非主节点执行insertQuery时,由于主键(region+lock)已存在,会触发DataIntegrityViolationException,进入catch块返回false
  • 这个流程会被非主节点反复执行,导致重复键冲突告警持续出现

想咨询该设计的底层原因:是不是插入失败的处理效率比单纯读取判断锁是否存在更高?虽然可以通过屏蔽告警解决问题,但希望理解这个实现逻辑,确认是否为最优方案。另外我们了解到可以通过设置自定义insertStatement来消除告警。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:10:00