Introduction to Liquibase Rollback – Liquibase Rollback简介

最后修改: 2017年 6月 16日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In our previous article, we showed Liquibase as a tool for managing database schemas and data.

在我们的前一篇文章中,我们展示了Liquibase作为管理数据库模式和数据的工具。

In this article, we’re going to look more into the rollback feature – and how we can undo a Liquibase operation.

在这篇文章中,我们将进一步研究回滚功能–以及我们如何撤消Liquibase的操作。

Naturally, this is a critical, feature of any production-grade system.

自然,这是任何生产级系统的一个关键特征。

2. Categories of Liquibase Migrations

2.Liquibase迁移的类别

There are two categories of Liquibase operations, resulting in a different generation of a rollback statement:

有两类Liquibase操作,导致不同的回滚语句的生成。

  • automatic, where migration can deterministically generate steps required for rolling back
  • manual, where we need to issue a rollback command because migration instruction cannot be used to identify the statement deterministically

For example, the rollback of a “create table” statement would be to “drop” the created table. This can be determined without a doubt, and therefore the rollback statement can be autogenerated.

例如,“创建表”语句的回滚将是”删除”创建的表。这一点可以确定无疑,因此可以自动生成回滚语句。

On the other hand, the rollback statement for a “drop table” command is not possible to be determined. It is not possible to determine the last state of the table, and therefore the rollback statement can’t be autogenerated. These types of migration statements require a manual rollback instructions.

另一方面,无法确定“drop table”命令的回滚语句。不可能确定表的最后状态,因此回滚语句不能自动生成。这些类型的迁移语句需要手动回滚指令。

3. Writing a Simple Rollback Statement

3.写一个简单的回滚声明

Let’s write a simple changeset which will create a table when executed and add a rollback statement to the changeset:

让我们写一个简单的变化集,它将在执行时创建一个表,并在变化集上添加一个回滚语句。

<changeSet id="testRollback" author="baeldung">
    <createTable tableName="baeldung_turorial">
        <column name="id" type="int"/>
        <column name="heading" type="varchar(36)"/>
        <column name="author" type="varchar(36)"/>
    </createTable>
    <rollback>
        <dropTable tableName="baeldung_test"/>
    </rollback>
</changeSet>

The above example falls under the first category mentioned above. It will create a rollback statement automatically if we do not add one. But we can override the default behavior by creating our rollback statement.

上面的例子属于上面提到的第一类。如果我们不添加回滚语句,它将自动创建一个回滚语句。但我们可以通过创建我们的回滚语句来覆盖默认的行为。

We can run the migration using the command:

我们可以用命令来运行迁移。

mvn liquibase:update

After the executing we can rollback the action using:

在执行后,我们可以使用回滚动作。

mvn liquibase:rollback

This executes the rollback segment of the changeset and should revert the task completed during the update stage. But if we issue this command alone, the build will fail.

这将执行变化集的回滚部分,并且应该恢复在更新阶段完成的任务。但是如果我们单独发布这个命令,构建就会失败。

The reason for that is – we do not specify the limit of rollback; the database will be completely wiped out by rolling back to the initial stage. Therefore it’s mandatory to define one of the three constraints below to limit the rollback operation when the condition is satisfied:

原因是–我们没有指定回滚的限制;数据库将通过回滚到初始阶段而被完全抹去。因此,当条件满足时,必须定义下面三个约束中的一个来限制回滚操作。

  • rollbackTag
  • rollbackCount
  • rollbackDate

3.1. Rolling Back to a Tag

3.1.回滚到一个标签

We can define a particular state of our database to be a tag. Therefore, we can reference back to that state. Rolling back to the tag name “1.0” looks like:

我们可以把数据库的一个特定状态定义为一个标签。因此,我们可以引用回那个状态。回滚到标签名 “1.0 “看起来像。

mvn liquibase:rollback -Dliquibase.rollbackTag=1.0

This executes rollback statements of all the changesets executed after tag “1.0”.

这将执行标签 “1.0 “之后执行的所有变化集的回滚语句。

3.2. Rolling Back by Count

3.2.按次数回滚

Here, we define how many changesets we need to be rolled back. If we define it to be one, the last changeset execute will be rolled back:

在这里,我们定义了我们需要回滚多少个变化集。如果我们把它定义为一个,最后执行的变化集将被回滚。

mvn liquibase:rollback -Dliquibase.rollbackCount=1

3.3. Rolling Back to Date

3.3.回滚到日期

We can set a rollback target as a date, therefore, any changeset executed after that day will be rolled back:

我们可以把回滚目标设定为一个日期,因此,在这一天之后执行的任何变化集都将被回滚。

mvn liquibase:rollback "-Dliquibase.rollbackDate=Jun 03, 2017"

The date format has to be an ISO data format or should match the value of DateFormat.getDateInstance() of the executing platform.

日期格式必须是ISO数据格式,或者应该符合执行平台的DateFormat.getDateInstance()的值。

4. Rollback Changeset Options

4.回滚更改集选项

Let’s explore what are the possible usages of rollback statement in changesets.

让我们来探讨一下回滚语句在变化集中可能有哪些用途。

4.1. Multistatement Rollback

4.1.多语句回滚

A single rollback tag may enclose more than one instruction to be executed:

一个回滚标签可以包含一条以上的要执行的指令。

<changeSet id="multiStatementRollback" author="baeldung">
    <createTable tableName="baeldung_tutorial2">
        <column name="id" type="int"/>
        <column name="heading" type="varchar(36)"/>
    </createTable>
    <createTable tableName="baeldung_tutorial3">
        <column name="id" type="int"/>
        <column name="heading" type="varchar(36)"/>
    </createTable>
    <rollback>
        <dropTable tableName="baeldung_tutorial2"/>
        <dropTable tableName="baeldung_tutorial3"/>
    </rollback>
</changeSet>

Here we drop two tables in the same rollback tag. We can split the task over multiple statements as well.

在这里,我们在同一个回滚标签中放弃了两个表。我们也可以把这个任务分成多个语句。

4.2. Multiple Rollback Tags

4.2 多重回滚标记

In a changeset, we can have more than one rollback tags. They are executed in the order of appearance in changeset:

在一个变化集中,我们可以有一个以上的回滚标签。它们按照在改变集中出现的顺序被执行。

<changeSet id="multipleRollbackTags" author="baeldung">
    <createTable tableName="baeldung_tutorial4">
        <column name="id" type="int"/>
        <column name="heading" type="varchar(36)"/>
    </createTable>
    <createTable tableName="baeldung_tutorial5">
        <column name="id" type="int"/>
        <column name="heading" type="varchar(36)"/>
    </createTable>
    <rollback>
        <dropTable tableName="baeldung_tutorial4"/>
    </rollback>
    <rollback>
        <dropTable tableName="baeldung_tutorial5"/>
    </rollback>
</changeSet>

4.3. Refer Another Changeset for Rollback

4.3.引用另一个更改集进行回滚

We can refer to another change set, possibly the original changeset if we are going to change some details of the database. This will reduce the code duplication and can correctly revert the done changes:

我们可以参考另一个变化集,如果我们要改变数据库的一些细节,可能是原始变化集。这将减少代码的重复,并能正确地恢复已完成的修改。

<changeSet id="referChangeSetForRollback" author="baeldung">
    <dropTable tableName="baeldung_tutorial2"/>
    <dropTable tableName="baeldung_tutorial3"/>
    <rollback changeSetId="multiStatementRollback" changeSetAuthor="baeldung"/>
</changeSet>

4.4. Empty Rollback Tag

4.4.空的回滚标签

By default, Liquibase tries to generate a rollback script if we have not provided. If we need to break this feature, we can have empty rollback tag so that rollback operation is not get reverted:

默认情况下,如果我们没有提供回滚脚本,Liquibase会尝试生成一个回滚脚本。如果我们需要破坏这个功能,我们可以使用空的回滚标签,这样回滚操作就不会被恢复。

<changeSet id="emptyRollback" author="baeldung">
    <createTable tableName="baeldung_tutorial">
        <column name="id" type="int"/>
        <column name="heading" type="varchar(36)"/>
        <column name="author" type="varchar(36)"/>
    </createTable>
    <rollback/>
</changeSet>

5. Rollback Command Options

5.回滚命令选项

Apart from rolling back a database to a previous state, Liquibase can be used in many different ways. Those are, generate the rollback SQL, create future rollback script, and finally, we can test the migration and rolling back, both in one step.

除了将数据库回滚到以前的状态外,Liquibase还可以在许多不同的方面使用。那就是,生成回滚SQL,创建未来的回滚脚本,最后,我们可以测试迁移和回滚,都在一个步骤中完成。

5.1. Generate Rollback Script

5.1.生成回滚脚本

Same as rolling back, we have three options in hand for generating rollback SQL. Those are:

和回滚一样,我们有三个选项来生成回滚SQL。它们是

  • rollbackSQL <tag> – a script for rollbacking the database to the mentioned tag
  • rollbackToDateSQL <date/time> – an SQL script to rollback the database to the state as of the mentioned date/time
  • rollbackCountSQL <value> – an SQL script to rollback the database to the state mentioned by number of steps before

Let’s see one of the examples in action:

让我们看看其中一个例子的实际情况。

mvn liquibase:rollbackCountSQL 2

5.2. Generate Future Rollback Script

5.2.生成未来的回滚脚本

This command generates the required rollback SQL commands to bring the database to the current state from the state, at which changesets eligible to run at the moment, have completed. This will be very useful if there is a need to provide a rollback script for a change we are about to perform:

这条命令生成所需的回滚SQL命令,使数据库从目前有资格运行的变更集完成的状态回到当前状态。如果需要为我们即将进行的变更提供一个回滚脚本,这将是非常有用的。

This will be very useful if there is a need to provide a rollback script for a change we are about to perform:

如果需要为我们即将进行的改变提供一个回滚脚本,这将是非常有用的。

mvn liquibase:futureRollbackSQL

5.3. Run Update Testing Rollback

5.3.运行更新测试回滚

This command executes the database update and then rolls back the changesets to bring the database to the current state. Both future rollback and update testing rollback does not alter the current database after the executing is finished. But update testing rollback performs the actual migration and then rolls it back.

这个命令执行数据库更新,然后回滚变化集,使数据库达到当前状态。未来回滚和更新测试回滚在执行完毕后都不会改变当前数据库。但是更新测试回滚执行了实际的迁移,然后回滚了。

This can be used to test te execution of update changes without permanently changing the database:

这可以用来测试更新变化的te执行,而不需要永久地改变数据库。

mvn liquibase:updateTestingRollback

6. Conclusion

6.结论

In this quick tutorial, we explored some command line and changeset features of the Liquibase rollback functionality.

在这个快速教程中,我们探索了Liquibase回滚功能的一些命令行和变化集功能。

As always, the source code can be found over on GitHub.

一如既往,源代码可以在GitHub上找到over