我正在对一个干净的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。)
答案 0 :(得分:3)
感谢您指出问题所在。目标是安全地同时运行,如果DATABASECHANGELOGLOCK表存在,它应该是好的,但是在检查表是否存在与尝试创建表之间存在时间间隔,如果不存在则可能导致您看到的错误如果时机恰到好处。
我创建https://liquibase.jira.com/browse/CORE-2596来跟踪问题并添加了3.4.2的修复程序,这将使Liquibase从“表已存在”异常中恢复。这将避免您的问题,并且插入表中的后续代码实际上是分布式锁定,因此您仍然可以安全地进行并发更新。