flyway项目中集成方式

项目集成方式

springboot2.x

pom

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>5.2.1</version>
</dependency>

配置文件

#开发时flyway.enabled调整为false
spring.flyway.enabled=true
spring.flyway.baseline-on-migrate=true
spring.flyway.clean-disabled=true

repair操作

于db.migration 文件夹下增加迁移文件:
afterMigrateError.sql

#下次启动服务时将自动清除上次失败的数据
DELETE FROM flyway_schema_history WHERE success=0;

springboot1.x配置方式

pom

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>4.2.0</version>
</dependency>

配置文件(注意springboot1.x版本以flyway.开头):

flyway.baseline-description=flyway
#开始执行基准迁移时对现有的schema的版本打标签,默认值为1.
flyway.baseline-version=1
#当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
flyway.baseline-on-migrate=true
#启用flyway
flyway.enabled=true
#配置数据库信息表的名称
flyway.table=flyway_schema_history
#sql编码
flyway.encoding=UTF-8
#当初始化好连接时要执行的SQL.
flyway.init-sqls=1
#sql文件位置
flyway.locations=classpath:db/migration
#是否允许无序的迁移,默认false
flyway.out-of-order=false
#sql文件前缀
flyway.sql-migration-prefix=V
#sql文件分隔符
flyway.sql-migration-separator=__
#sql文件后缀
flyway.sql-migration-suffix=.sql

repair操作

于db.migration 文件夹下增加迁移文件:
afterMigrateError.sql

#下次启动服务时将自动清除上次失败的数据
DELETE FROM flyway_schema_history WHERE success=0;

springmvc配置方式

pom

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>5.2.1</version>
</dependency>

配置文件

<bean id="flyway" class="org.flywaydb.core.Flyway" init-method="migrate" depends-on="dataSource">
    <property name="dataSource" ref="dataSource" /> <!--数据源-->
    <property name="locations" value="classpath:/db/migration"/> <!--脚本文件夹地址 默认src/db/migration-->
    <property name="validateOnMigrate" value="false"/> <!--迁移验证 默认true-->
    <property name="baselineOnMigrate" value="true"/> <!--基线迁移 默认false-->
    <property name="cleanDisabled" value="true"/>
</bean>

repair操作

于db.migration 文件夹下增加迁移文件:
afterMigrateError.sql

#下次启动服务时将自动清除上次失败的数据
DELETE FROM flyway_schema_history WHERE success=0;

springboot2.x多数据源配置

//假设存在primary、secondary两个库,数据源配置略
1、构建DataSource的方法上可以加上注解@FlywayDataSource

2、两个库的sql文件分别在db/migration/primary,db/migration/secondary文件夹下
   flyway sql文件整理方式 见 【flyway sql文件整理方式】

3、在启动类移除flyway自动配置,如下:   
@SpringBootApplication(exclude= FlywayAutoConfiguration.class)

4、实现CommandLineRunner接口 run()方法
//以下魔法值需在配置文件中处理,此处略
@Component
public class FlyConfiguration implements CommandLineRunner  {
    
    @Resource
    private DataSource primaryDataSource;
    
    @Resource
    private DataSource secondaryDataSource;
    
    @Override
    public void run(String... args) throws Exception {
        
        Flyway primaryFlyway = Flyway.configure().dataSource(primaryDataSource)
                .locations("db/migration/primary").cleanDisabled(true).baselineOnMigrate(true).load();
        primaryFlyway.migrate();
        
        Flyway secondaryFlyway = Flyway.configure().dataSource(secondaryDataSource)
                .locations("db/migration/secondary").cleanDisabled(true).baselineOnMigrate(true).load();
        secondaryFlyway.migrate();
    }
}  

repair操作

于每个库指定的文件夹下增加迁移文件:
afterMigrateError.sql

#下次启动服务时将自动清除上次失败的数据
DELETE FROM flyway_schema_history WHERE success=0;

注意事项

依赖环境最新版需jdk 8以上(1.7需enterprise版,每年3000美元,或flyway4.2.0也支持jdk1.7)
Maven 3.x
mysql5.7以上(5.1、5.5、5.6需enterprise版)
Oracle12.2以上(10.112.1需enterprise版)<br>SQLSERVER2016以上(20182014需enterprise版)
flyway通常需要在数据库存在的情况下才能操作
数据库账号权限由于涉及ddl操作,因此账号权限级别有要求。如果存在对表结构的变动,启动时需要有alter、drop、create、index权限。服务启动后再收回权限。
默认配置如上
文件路径#无需配置,默认路径为resource文件夹下的db/migration,非多数据源情况下不推荐更换路径
#但需注意flyway会穷尽此文件下的所有sql文件,即便此文件夹下还有文件夹
spring.flyway.locations=classpath:db/migration
不同环境下的处理方式:不同环境的数据库表结构应是相同的。
需保证上线前的sql文件在测试环境得到过验证。
不得在测试通过后再次提交sql文件。
文档命名方式见下方
文档内容每一个sql 文件会有一个单独的事务,如果单个文件中发生错误,单个文件的操作会回滚,
比如有1、2、3三个 文件,第二个文件发生错误,第二个文件所有操作将会回滚,第三个文件不会执行。
但: Unfortunately, today only DB2, PostgreSQL, Derby, EnterpriseDB and to a certain extent SQL Server support DDL statements inside a transaction。
所以,建议不要把ddl语句和dml语句放在同一个迁移文件里,避免不必要的麻烦,否则dml语句将不能正常回滚。
文档变更不得随意删除或更新已执行过的文件。
flyway会在flyway_schema_history表中记录当前执行的版本以确定下次要执行的版本,但flyway仍会扫描历史文件是否有改动,通过checksum值对历史版本校验。
如果更新了历史文件中的sql语句,flyway通过算法计算出的checksum值与数据库相应版本中输入的checksum值不一致,将会报错,服务也将不能正常启动。

文件路径

flyway通过flyway.locations指定sql文件路径,默认设置为:classpath:db/migration。
也可以是filesystem:/my-project/my-other-folder。如下图:
在这里插入图片描述

注意,flyway将以递归的形式扫描指定路径下的所有sql文件。

文件命名方式

  • Version Migrations:通常命名形式为Vversion__description.sql
    默认 v e r s i o n 长 度 小 于 50 , version长度小于50, version50description长度小于500,以__分隔
    v e r s i o n 按 升 序 , version按升序, versiondescription可以重复
  • Undo Migrations:Version Migrations的相反操作,flyway pro支持,但事实上目前需求通过Version Migrations也能够实现。
  • Repeatable Migrations:可重复操作文件。由于可重复操作,但上线发版却只有一次,即只会执行最后一次提交的结果。原则上不推荐使用此操作文件,除非只在原文件基础上只增不减。Repeatable Migrations在Version Migrations 执行完后再执行。同时可以有多个Repeatable Migrations文件,按升序执行。
    在这里插入图片描述

Version Migrations默认基准版本号为1,且版本号升序执行,因此文件名V后的版本号需大于等于1
文档名命名规范为V{version}__${description}.sql
注意,默认版本号与描述之间以两个“_”隔开
示例:V1.0.0.0__initDatabase.sql
1、如果为空数据库,起始版本号可以等于1
2、如果数据库不为空,起始版本号需大于1

多人协作开发同一项目情况下,对数据库改动后,需及时提交版本文件。
项目启动前,需更新代码,保证未执行的版本大于系统当前已执行过的版本,否则会抛出异常,导致服务不能正常启动。

由于flyway将按顺序执行版本文件,因此如果版本文件之间有依赖关系,【被依赖的文件的版本号】应当小于【依赖此文件的文件的版本号】

文件格式

默认文件格式为sql文件,但如果存在sql解决不了的复杂逻辑,可以编写java格式文件,参照如下:
文件名命名方式同sql文件
JAVA&JDBC模式:

package db.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import java.sql.PreparedStatement;

/**
 * Example of a Java-based migration.
 */
public class V1_2__Another_user extends BaseJavaMigration {
    public void migrate(Context context) throws Exception {
        try (PreparedStatement statement = 
                 context
                     .getConnection()
                     .prepareStatement("INSERT INTO test_user (name) VALUES ('Obelix')")) {
            statement.execute();
        }
    }
}

Spring:

package db.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import java.sql.PreparedStatement;

/**
 * Example of a Java-based migration using Spring JDBC.
 */
public class V1_2__Another_user extends BaseJavaMigration {
    public void migrate(Context context) {
        new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), true))
                .execute("INSERT INTO test_user (name) VALUES ('Obelix')");
    }
}

记录修复

不得随意使用flyway.repair方法,误用此方法可能会导致不同环境数据库不一致的情况。

迁移文件最好能先验证一遍。repeated | version sql语句执行失败后,仍然会创建一条success=0的记录。而且此sql语句修改后在下次执行迁移(migrate)操作时仍会提示失败。
解决办法有如下几种:

  • 如果有操作数据库的权限,手动将表(flyway_schema_history)中失败记录删除掉
  • 增加回调sql脚本文件,afterMigrateError.sql
DELETE FROM flyway_schema_history WHERE success=0;
  • 实现FlywayMigrationStrategy接口重写migrate方法(不推荐)
@Override
public void migrate(Flyway flyway) {
     //flyway.repair方法有两个作用,移除success=0的数据,调整success=1数据的checksum值,
     //但并不真正执行更改后的sql文件,因此误用此方法可能会导致不同环境数据库不一致的情况。
     flyway.repair();
     flyway.migrate();
}

不建议捕获flyway.migrate()的异常,可能导致部分异常被捕获后未处理即发版上线

回调事件列表

org.flywaydb.core.api.callback.Event

在这里插入图片描述
在这里插入图片描述

并发支持

flyway支持集群情况下并发部署

Can multiple nodes migrate in parallel?
Yes! Flyway uses the locking technology of your database to coordinate multiple nodes. This ensures that even if multiple instances of your application attempt to migrate the database at the same time, it still works. Cluster configurations are fully supported.

flyway通过锁住flyway_schema_history表来支持并发部署

/**
 * Locks this table and executes this callable.
 *
 * @param table    The table to lock.
 * @param callable The callable to execute.
 * @return The result of the callable.
 */
public <T> T lock(final Table table, final Callable<T> callable) {
    return new TransactionTemplate(jdbcTemplate.getConnection(), database.supportsDdlTransactions()).execute(new Callable<T>() {
        @Override
        public T call() throws Exception {
            table.lock();
            return callable.call();
        }
    });
}

并发实验结果如下图(三台服务,不同数据库账号同时访问,execution_time 时间较长是因为执行了select sleep())
在这里插入图片描述

参考文档

1、https://flywaydb.org/documentation/migrations#sql-based-migrations
2、https://github.com/flyway/flyway
3、https://docs.spring.io/spring-boot/docs/1.4.0.RC1/reference/htmlsingle/#howto-execute-flyway-database-migrations-on-startup
4、https://flywaydb.org/documentation/command/repair
5、https://stackoverflow.com/questions/37462550/flyway-repair-with-spring-boot
6、https://flywaydb.org/documentation/faq
7、https://flywaydb.org/documentation/callbacks.html
8、https://flywaydb.org/documentation/api/hooks#callsbacks

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值