简体   繁体   English

具有Spring Boot和多个模式的Liquibase,如何指定执行顺序

[英]Liquibase with Spring Boot and multiple schemas, how to specify execution order

We have an data-migration job which needs to initialize schemas A and B , in that order. 我们有一个数据迁移作业,需要按此顺序初始化模式AB We handle multiple schemas by defining multiple SpringLiquibase , one for each schema, each with its own datasource and its own master changeset. 我们通过定义多个SpringLiquibase处理多个模式,每个模式一个,每个都有自己的数据源和自己的主变更集。 (Note, normally in Spring Boot you wouldn't need to define a SpringLiquibase, because it would detect a single datasource and auto-configure the SpringLiquibase for you with that datasource.) (请注意,通常在Spring Boot中,您不需要定义SpringLiquibase,因为它会检测单个数据源并使用该数据源为您自动配置SpringLiquibase。)

The execution order seems to vary depending whether the job is run locally within the IDE, or bundled as a single-JAR Spring Boot app. 执行顺序似乎有所不同,具体取决于作业是在IDE中本地运行还是作为单个JAR Spring Boot应用程序捆绑在一起。

How can we ensure that the two executions of liquibase happen in the order we want? 我们如何确保liquibase的两次执行按我们想要的顺序进行?

(Why the order is important: A contains some tables, while B contains views that reference tables in A . We have to make sure that we grant select on A.* to B before attempting to create view B.some_view (...) as select ... from A.xyz , otherwise the creation of B fails due to insufficient privileges.) (为什么顺序很重要: A包含一些表,而B包含引用表中的观点A ,我们必须确保我们grant select on A.* to B尝试之前create view B.some_view (...) as select ... from A.xyz ,否则由于权限不足而无法创建B。)

After some scratching of heads and digging into the source code, it turns out to be extremely simple. 经过一番摸索和深入研究源代码,事实证明它非常简单。

SpringLiquibase implements InitializingBean and executes the Liquibase update within the InitializingBean.afterPropertiesSet() method. SpringLiquibase实现InitializingBean并在InitializingBean.afterPropertiesSet()方法内执行Liquibase更新。

Spring calls this method on each bean, one by one, after finishing initializing each one. 在完成对每个bean的初始化之后,Spring在每个bean上一个接一个地调用此方法。

So to force a particular order, you need to force the order in which the beans are defined in the Spring context. 因此,要强制执行特定顺序,您需要强制在Spring上下文中定义Bean的顺序。 And the easiest way to do this is with the @DependsOn annotation. 最简单的方法是使用@DependsOn批注。

So we put in place something like: 因此,我们将以下内容设置为:

@Bean
public SpringLiquibase liquibaseA(
    @Qualifier("dataSourceA") DataSource dataSource,
    @Qualifier("liquibasePropertiesA") LiquibaseProperties liquibaseProperties
) {
    return instantiateSpringLiquibase(dataSource, liquibaseProperties); 
}

@Bean
@DependsOn("liquibaseA")
public SpringLiquibase liquibaseB(
    @Qualifier("dataSourceB") DataSource dataSource,
    @Qualifier("liquibasePropertiesB") LiquibaseProperties liquibaseProperties
) {
    return instantiateSpringLiquibase(dataSource, liquibaseProperties); 
}

private SpringLiquibase instantiateSpringLiquibase(DataSource dataSource, LiquibaseProperties liquibaseProperties) {
    // set the datasource from dataSource and everything else from liquibaseProperties
}

This is not for spring boot but if you manage your migrations via the change logs this workaround will help. 这不是用于春季启动,但如果您通过更改日志管理迁移,则此解决方法将有所帮助。 This assumes you have different data sources for different schemas. 假设您具有用于不同模式的不同数据源。

<bean id="liquibase1" class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource1" />
      <property name="changeLog" value="classpath:db1-changelog1.xml" />
 </bean>
 <bean id="liquibase2" depends-on="liquibase1" class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource2" />
      <property name="changeLog" value="classpath:db2-changelog1.xml" />
 </bean>
<bean id="liquibase3" depends-on="liquibase2"  class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource1" />
      <property name="changeLog" value="classpath:db1-changelog2.xml" />
 </bean>
<bean id="liquibase4" depends-on="liquibase3"  class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource2" />
      <property name="changeLog" value="classpath:db2-changelog2.xml" />
 </bean>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring Boot 多个 CommandLineRunner 执行顺序和状态 - Spring Boot multiple CommandLineRunner execution order and state 弹簧靴中的多个liquibase配置 - Multiple liquibase configurations in spring boot 如何使用Spring的Java配置指定过滤器执行顺序? - How to specify Filter execution order using Spring's Java Configuration? 如何在请求正文中指定订单验证 Spring 启动 Rest Controller - How to specify order validation in Request body Spring Boot Rest Controller 如何在 Junit5 / spring 引导中命令执行 controller 测试类? - How to order execution of controller test classes in Junit5 / spring boot? liquibase changelogsync 与 spring 启动 - liquibase changelogsync with spring boot 如何在Spring Boot中为Freemarker指定多个templateLoaderPaths? - How do I specify multiple templateLoaderPaths for Freemarker in Spring Boot? 带有多个架构/数据库的Spring-boot应用程序中的实体管理器错误 - Entity manager error in spring-boot application with multiple schemas/databases Spring Boot - 如何实现这个执行? - Spring Boot - How to achieve this execution? 如何更改此 Spring Batch @Scheduled() 注释以指定执行时间和时间? - How to change this Spring Batch @Scheduled() annotation in order to specify execution hour and time?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM