集群环境下Liquibase Migrations并发执行防重复方案问询
Liquibase多实例部署下的脚本执行互斥机制
Liquibase内置的分布式锁机制
Liquibase原生支持分布式锁,专门解决多实例同时执行变更脚本的问题,核心逻辑是:
- 自动在数据库中创建并维护
DATABASECHANGELOGLOCK表(名称可配置),当实例启动变更流程时,会尝试获取该表中的独占锁——通过更新表中唯一记录的LOCKED字段为true,同时记录锁持有者和时间戳。 - 其他实例触发变更时,会先检查锁状态,若锁已被持有则进入等待,直到锁被正常释放(变更执行完成)或超时后强制接管。
你遇到的重复插入场景分析
你碰到的罕见重复问题,大概率是边缘情况导致锁机制失效:
- 遗留表异常:如果
DATABASECHANGELOGLOCK表存在结构缺陷(比如字段缺失、权限不足),或者历史数据干扰了锁逻辑,会让Liquibase无法正确获取/释放锁。 - 脚本未纳入变更集:如果插入操作是通过原生SQL直接执行,而非通过Liquibase的
<insert>或<sql>标签管理,锁机制无法覆盖这类脱离管控的操作。 - 锁异常释放:极端场景下,持有锁的实例意外崩溃,锁未正常释放,后续实例超时后强制获取锁,若原实例恢复后继续执行,就会出现并行操作。
参考Quartz集群思路的补充方案
如果需要针对特定场景强化互斥逻辑,可以参考Quartz的集群锁思路:
- 自定义细粒度锁:在关键插入脚本执行前,手动通过数据库语句获取独占锁(比如
SELECT * FROM your_lock_table WHERE lock_key='insert_data' FOR UPDATE),执行完成后释放锁。 - 强制脚本幂等性:从根源避免重复,把插入语句改成幂等形式,比如用
INSERT ... ON DUPLICATE KEY UPDATE(MySQL)或MERGE(Oracle/PostgreSQL),即使并行执行也不会产生重复数据。
内容的提问来源于stack exchange,提问作者K.Niemczyk
相关产品推荐
相关产品推荐

