Liquibase 应该处理并发初始化吗?
Should Liquibase cope with concurrent initialisation?
我正在运行同时针对一个干净的 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 在应用程序节点启动时。)
感谢您指出问题。目标是同时安全 运行,如果 DATABASECHANGELOGLOCK table 存在应该很好,但是检查 table 是否存在和尝试创建它之间存在时间间隔如果时间只是 right/wrong.
,那不会导致您看到的错误
我创建了 https://liquibase.jira.com/browse/CORE-2596 来跟踪问题并添加了 3.4.2 的修复程序,这将使 Liquibase 从 "table already exists" 异常中恢复。这将避免您的问题,稍后插入 table 的代码才是分布式锁定的真正作用,因此您仍然可以避免并发更新。
我正在运行同时针对一个干净的 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 在应用程序节点启动时。)
感谢您指出问题。目标是同时安全 运行,如果 DATABASECHANGELOGLOCK table 存在应该很好,但是检查 table 是否存在和尝试创建它之间存在时间间隔如果时间只是 right/wrong.
,那不会导致您看到的错误我创建了 https://liquibase.jira.com/browse/CORE-2596 来跟踪问题并添加了 3.4.2 的修复程序,这将使 Liquibase 从 "table already exists" 异常中恢复。这将避免您的问题,稍后插入 table 的代码才是分布式锁定的真正作用,因此您仍然可以避免并发更新。