Liquibase应该同时进行初始化吗?

时间:2015-11-17 21:49:20

标签: liquibase

我正在对一个干净的HSQLDB实例同时运行Liquibase迁移,而其中一个更新成功,另一个更新失败:

Exception in thread "Thread-7" liquibase.exception.LockException: liquibase.exception.DatabaseException: object name already exists: DATABASECHANGELOGLOCK in statement [CREATE TABLE PUBLIC.DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID))] [Failed SQL: CREATE TABLE PUBLIC.DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID))]
    at liquibase.lockservice.StandardLockService.acquireLock(StandardLockService.java:216)
    at liquibase.lockservice.StandardLockService.waitForLock(StandardLockService.java:155)
    at liquibase.Liquibase.update(Liquibase.java:194)
    at liquibase.Liquibase.update(Liquibase.java:190)
    at liquibase.Liquibase.update(Liquibase.java:186)
    at liquibase.Liquibase.update(Liquibase.java:179)
Caused by: liquibase.exception.DatabaseException: object name already exists: DATABASECHANGELOGLOCK in statement [CREATE TABLE PUBLIC.DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID))] [Failed SQL: CREATE TABLE PUBLIC.DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID))]
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:316)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:55)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:122)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:112)
    at liquibase.lockservice.StandardLockService.init(StandardLockService.java:87)
    at liquibase.lockservice.StandardLockService.acquireLock(StandardLockService.java:189)

这是预期的行为吗?使用Liquibase 3.4.1。

(原因是它是一个自动化测试,启动了一个干净的环境,有两个应用程序节点强制代码处理多个节点,我在应用程序节点启动时运行Liquibase。)

1 个答案:

答案 0 :(得分:3)

感谢您指出问题所在。目标是安全地同时运行,如果DATABASECHANGELOGLOCK表存在,它应该是好的,但是在检查表是否存在与尝试创建表之间存在时间间隔,如果不存在则可能导致您看到的错误如果时机恰到好处。

我创建https://liquibase.jira.com/browse/CORE-2596来跟踪问题并添加了3.4.2的修复程序,这将使Liquibase从“表已存在”异常中恢复。这将避免您的问题,并且插入表中的后续代码实际上是分布式锁定,因此您仍然可以安全地进行并发更新。