Flyway 数据库迁移在部署新战争时自动运行

Posted

技术标签:

【中文标题】Flyway 数据库迁移在部署新战争时自动运行【英文标题】:Flyway database migration to run automatically when new war deployed 【发布时间】:2016-09-06 11:32:18 【问题描述】:

每当我向服务器部署新战争时,我希望 Flyway 运行。

部署服务器时flyway会自动运行吗?我是否必须始终自动化一个脚本,然后执行 flyway 迁移命令?或者最好的方法是什么?

服务器

服务器是运行在 Elastic Beanstalk (AWS) 上的 Java Tomcat 服务器,它连接到 mysql 数据库。

部署流程

我们在数据库上手动运行我们的 sql 迁移脚本。然后我们将服务器的新战争上传到 Elastic Beanstalk。

【问题讨论】:

不行,你得自己开Flyway。可以作为部署的一部分通过命令行脚本完成,也可以作为 Web 应用程序启动过程的一部分自动完成。 集成 Flyway 迁移触发有多种选择。如果您详细说明您的应用程序设计,我们可以给出更好的答案。 @Thomas 刚刚添加了更多信息,如果我可以添加其他有用的信息,请告诉我 【参考方案1】:

这很有用:

启动时自动迁移:https://flywaydb.org/documentation/api/

因此,对于 Java,只需创建脚本(例如 V1__initial_schema.sql,...),将它们放在 /src/main/resources/db/migration/ 下 然后:

Flyway flyway = new Flyway();
flyway.setDataSource(...);
flyway.migrate();

【讨论】:

【参考方案2】:

正如 cmets 所说,可能有多种方法可以做到这一点。

ServletContextListener

一种常见的方法是使用Java Servlet spec 定义的挂钩,以便在您的网络应用程序启动和关闭时收到通知。那个钩子就是ServletContextListener 接口。将一个类添加到您的项目中,实现此接口中的两种方法,一种用于启动,一种用于关闭。在启动方法中,运行您的 Flyway 代码。

“上下文”一词是指您的网络应用的技术术语。

contextInitialized您的网络应用程序正在启动。尚未处理任何传入的 Web 请求,并且在您完成此方法的实现之前不会处理。在此处运行您的 Flyway 迁移。 contextDestroyed您的网络应用程序正在关闭。最后剩余的 Web 请求已得到处理,不再接受。

使用@WebListener 注释此类是让Servlet container 注册实例的多种方法中最简单的一种。

很简单。

您的ServletContextListener 保证在您的网络应用程序中第一次执行任何 Servlet(或过滤器)之前被调用并运行完成。因此,这是您希望在 servlet 开始工作之前完成的设置工作的理想场所。 Flyway 似乎很适合我。

在 Stack Overflow 中搜索“ServletContextListener”以了解更多信息并查看示例,例如 my own Question & Answer。

处理失败

请注意,当出现问题时(当您的 ServletContextListener 遇到异常时)停止 Web 应用程序的部署在 Servlet 规范中没有明确定义。

一个示例可能是您的 Flyway 迁移由于某种原因失败,例如无法连接到数据库。此时,您可能想要停止 Web 应用程序的部署。

查看我自己的Question and Answer 以及我在该答案中列出的相关问题组。 Tomcat 8.0.33 停止部署,并取消部署 Web 应用程序,但不幸的是没有报告有问题的异常(或者至少在开发模式下我在日志和 IDE 控制台中找不到任何此类报告)。其他 Servlet 容器的行为可能会有所不同。

【讨论】:

以上是关于Flyway 数据库迁移在部署新战争时自动运行的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot整合Flyway

SpringBoot整合Flyway

在 docker 容器上运行数据库时,Flyway 找不到迁移

每次战争部署仅创建一次 hsqldb 数据库

Elasticsearch 的 Liquibase 或 Flyway 数据库迁移替代方案

尝试在 sql-server 上迁移时 Flyway 挂起