Java中的Liquibase回滚似乎不起作用

时间:2014-03-09 01:49:31

标签: java unit-testing integration-testing liquibase

我使用Liquibase作为Java集成测试的一部分。在集成测试阶段,我使用Liquibase在@BeforeClass函数中创建和填充我的表。我的变更集在应用后会被标记。在@After函数中,我运行回滚到特定标记。

然后我可以从数据库和INSERT运行单元测试到SELECT。但是,然后我尝试在每次测试后回滚更改,并发现Liquibase没有回滚我的更改。

我正在对嵌入式Derby数据库使用Liquibase 3.1.1。

我的变更集文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

<include file="create-table-event-type.xml" relativeToChangelogFile="true"/>
<include file="load-table-event-type.xml" relativeToChangelogFile="true"/>

<include file="create-table-event.xml" relativeToChangelogFile="true"/>
<include file="load-table-event.xml" relativeToChangelogFile="true"/>

<changeSet id="tag-integration-test-database" author="Ivan Suftin" context="integration-test">
    <tagDatabase tag="integration-tests-tag" />
</changeSet>

</databaseChangeLog>

我的单元测试:

@Category(IntegrationTest.class)
public class EventDAOTest {

private static Connection conn;
private static SqlSessionFactory sqlSessionFactory;
private static Liquibase liquibase;
private EventDAO instance = null;
private static final String rollbackTag = "integration-tests-tag";
private static final Contexts contexts = new Contexts("integration-test");

public EventDAOTest() {
}

@BeforeClass
public static void setUpClass() throws ClassNotFoundException, SQLException, DatabaseException, LiquibaseException, InstantiationException, IllegalAccessException, IOException {
    String port = System.getProperty("db.twitter.integration-test.port");
    String driver = System.getProperty("db.twitter.integration-test.driver");
    String dbType = System.getProperty("db.twitter.integration-test.dbtype");
    String schema = System.getProperty("db.twitter.integration-test.schema");
    if (StringUtils.isBlank(port)) {
        throw new NullPointerException("System property \"db.twitter.integration-test.port\" not found");
    }
    if (StringUtils.isBlank(driver)) {
        throw new NullPointerException("System property \"db.twitter.integration-test.driver\" not found");
    }
    if (StringUtils.isBlank(dbType)) {
        throw new NullPointerException("System property \"db.twitter.integration-test.dbType\" not found");
    }
    if (StringUtils.isBlank(schema)) {
        throw new NullPointerException("System property \"db.twitter.integration-test.schema\" not found");
    }

    Class.forName(driver).newInstance();

    conn = DriverManager.getConnection("jdbc:" + dbType + "://localhost:" + port + "/" + schema + ";create=true", "test", "test");

    Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn));
    liquibase = new Liquibase("src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml", new FileSystemResourceAccessor(), database);

    liquibase.update(contexts);

    try (InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml")) {
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, "integration-test");
    }
}


@AfterClass
public static void tearDownClass() throws SQLException {
    conn.close();
}

@Before
public void beforeTest() {
    instance = new EventDAO(sqlSessionFactory);
}

@After
public void afterTest() throws DatabaseException, LiquibaseException {
    liquibase.rollback(rollbackTag, contexts);
}

[...]

测试的其余部分只是我使用MyBatis进行SELECT和INSERT。

这是日志的样子(只是粘贴重要部分)

INFO 3/8/14 7:23 PM:liquibase: Successfully acquired change log lock
INFO 3/8/14 7:23 PM:liquibase: Creating database history table with name: TEST.DATABASECHANGELOG
INFO 3/8/14 7:23 PM:liquibase: Reading from TEST.DATABASECHANGELOG

[...运行变更集...]

INFO 3/8/14 7:23 PM:liquibase: src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml: tag-integration-test-database::Ivan Suftin: Reading from TEST.DATABASECHANGELOG
INFO 3/8/14 7:23 PM:liquibase: src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml: tag-integration-test-database::Ivan Suftin: Tag 'integration-tests-tag' applied to database
INFO 3/8/14 7:23 PM:liquibase: src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml: tag-integration-test-database::Ivan Suftin: ChangeSet src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml::tag-integration-test-database::Ivan Suftin ran successfully in 11ms
INFO 3/8/14 7:23 PM:liquibase: src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml: tag-integration-test-database::Ivan Suftin: Reading from TEST.DATABASECHANGELOG
INFO 3/8/14 7:23 PM:liquibase: Successfully released change log lock

在每次测试之间,我尝试运行回滚,所以我得到一个新加载的数据库,并在此处显示日志:

INFO 3/8/14 7:23 PM:liquibase: Successfully acquired change log lock
INFO 3/8/14 7:23 PM:liquibase: Reading from TEST.DATABASECHANGELOG
INFO 3/8/14 7:23 PM:liquibase: Reading from TEST.DATABASECHANGELOG
INFO 3/8/14 7:23 PM:liquibase: Successfully released change log lock
-- *********************************************************************
-- Rollback to 'integration-tests-tag' Script
-- *********************************************************************
-- Change Log: src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml
-- Ran at: 3/8/14 7:23 PM
-- Against: test@jdbc:derby://localhost:59527/twitter;create=true
-- Liquibase version: 3.1.1
-- *********************************************************************

-- Lock Database
-- Rolling Back ChangeSet: src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml::tag-integration-test-database::Ivan Suftin
DELETE FROM TEST.DATABASECHANGELOG  WHERE ID='tag-integration-test-database' AND AUTHOR='Ivan Suftin' AND FILENAME='src/main/resources/liquibase/changelogs/create-table-parent-changeLog.xml';

-- Release Database Lock

我测试的表最初有两行。我有两个插入测试。他们一个接一个地跑。在第一个测试中,我运行一行INSERT,然后立即运行SELECT来计算行数。结果显示3行,这是正确的。

下一个测试还运行一行INSERT,然后我再次运行SELECT来测试行数,它应该是3行,但现在我得到4行。这告诉我@After函数中的回滚实际上什么都不做。

我在这里做错了吗?

我还尝试使用Java API在运行更改日志后立即创建标记:

liquibase.tag(rollbackTag); 

...但我得到了相同的结果。什么都没有回滚。

1 个答案:

答案 0 :(得分:5)

Liquibase不会自动为insert语句生成回滚命令,因此除非你手动将它们放入Liquibase中,否则不会做任何事情。有关该文档,请参阅http://www.liquibase.org/documentation/rollback.html

  

许多重构,例如“创建表”,“重命名列”和“添加”   列“可以自动创建回滚语句。如果你改变了   log只包含适合此类别的语句   回滚命令将自动生成。

     

其他重构,例如“drop table”和“insert data”都没有   可自动生成的相应回滚命令。   在这些情况下,以及您要覆盖默认值的情况   生成的回滚命令,可以通过指定回滚命令   changeSet标记中的标记。如果你不想做任何事情   撤消回滚模式的更改,使用空标记。