【问题标题】:From within Java, Liquibase update is hanging after applying a changeset在 Java 中,Liquibase 更新在应用变更集后挂起
【发布时间】:2013-11-14 11:27:03
【问题描述】:

我正在使用 Liquibase 进行单元测试的迁移。我使用一个名为 ${projectName}Liquibase.java 的类来存储两个静态函数

public class ${projectName}Liquibase {
  ...
  public static void runMigrations(Connection conn, DB_TYPE dbType) {
           Liquibase liquibase;
    Database database = null;
    try {
        database = DatabaseFactory.getInstance()
                                  .findCorrectDatabaseImplementation(new JdbcConnection(conn));
        liquibase = new Liquibase(dbType.filePath, new FileSystemResourceAccessor(), database);
        liquibase.validate();
        liquibase.update(null);
    } catch (LiquibaseException e) {
        throw new RuntimeException("File at " + dbType.filePath + " Error: " + e.getMessage());
    }
  }
  public static void dropTables() {
    ...
  }
}

我通过使用 System.getProperty("user.dir") 和路径的其余部分来获取文件 dbType.filePath 参数。

文件读取正常,但是,更新仅通过第一个变更集,然后在测试期间挂起。因此,测试不会运行。

测试从我的 Intellij 项目中的其他文件和子模块成功运行。特别是,我们的集成测试套件使用来自不同子模块的相同接口成功运行。所有的测试都将通过,直到这个:

Running *.*.*.*.*.*DAOTest
2013-11-03 14:59:53,144 DEBUG [main] c.j.bonecp.BoneCPDataSource   : JDBC URL = jdbc:hsqldb:mem:*, Username = SA, partitions = 2, max (per partition) = 5, min (per partition) = 5, helper threads = 3, idle max age = 60 min, idle test period = 240 min
INFO 11/3/13 2:59 PM:liquibase: Reading from PUBLIC.DATABASECHANGELOG
INFO 11/3/13 2:59 PM:liquibase: Successfully acquired change log lock
INFO 11/3/13 2:59 PM:liquibase: Reading from PUBLIC.DATABASECHANGELOG
INFO 11/3/13 2:59 PM:liquibase: /Users/davidgroff/repo/services/${projectName}/server/../core/src/main/java/com/*/*/liquibase/hsqldb.sql: 1::davidgroff: Custom SQL executed
INFO 11/3/13 2:59 PM:liquibase: /Users/davidgroff/repo/services/${projectName}/server/../core/src/main/java/com/*/*/liquibase/hsqldb.sql: 1::davidgroff: ChangeSet /Users/davidgroff/repo/services/*/*/../core/src/main/java/com/*/*/liquibase/hsqldb.sql::1::davidgroff ran successfully in 3ms
INFO 11/3/13 2:59 PM:liquibase: Successfully released change log lock

在此之后,测试反复挂起,就像在某个无限循环中一样。

我有当前的设置:

      <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
        <version>3.0.6</version>
      </dependency>
      <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-maven-plugin</artifactId>
        <version>3.0.6</version>
      </dependency>

我在 Maven 3.1.0 上使用 Java 7。

【问题讨论】:

    标签: java maven jdbc intellij-idea liquibase


    【解决方案1】:

    可能是一个单独的事务锁定了数据库中的一行,而 Liquibase 正在挂起等待另一个事务完成。

    您说“更新仅通过第一个变更集,然后在测试期间挂起”,这是否意味着第一个变更集成功运行?如果是这种情况,那么锁定的记录要么是 DATABASECHANGELOG 表上的表锁,它会阻止 INSERT INTO DATABASECHANGELOG 完成,要么是你的第二个 changeSet 有问题。

    假设 DATABASECHANGELOG 表有问题,是否有单独的线程或进程试图从该表中删除?

    【讨论】:

    • 经过更多调试后,JUnit 测试似乎在 SQLUpdates 期间挂起。正如您在上面看到的,liquibase 具有“成功释放更改日志锁”。但是当我在无限循环期间暂停程序时,有很多线程。但是,它们似乎都没有错误。除了正在运行的信号调度器之外,它们都在等待。
    • 我还应该提到我正在使用 BoneCP 来管理连接池。但是 liquibase 更新运行成功,这表明 liquibase 关闭其连接的方式可能存在问题。我不知道这种行为是在哪里发生的。
    • Liquibase 不会尝试关闭连接本身。它被传递给 Connection 对象,因此假定它是在 Liquibase 之外进行管理的。也许您只需要在 runMigrations 方法结束时调用 conn.close()。
    【解决方案2】:

    问题原来是在使用命令应用 liquibase 变更集后正在创建和使用连接,

    connection.createStatement(..."***SQL***"...);
    

    并且从未提交到数据库,因为创建了新连接或该连接没有数据。在我们使用 Liquibase 运行迁移之前,为什么它会起作用是一个谜。解决方法就是通过调用提交上述语句:

    connection.commit();
    

    【讨论】:

      猜你喜欢
      • 2018-01-01
      • 2015-10-27
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      • 2014-05-20
      相关资源
      最近更新 更多