Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Spring引导和多个模式进行Liquibase,如何指定执行顺序_Java_Spring Boot_Liquibase - Fatal编程技术网

Java 使用Spring引导和多个模式进行Liquibase,如何指定执行顺序

Java 使用Spring引导和多个模式进行Liquibase,如何指定执行顺序,java,spring-boot,liquibase,Java,Spring Boot,Liquibase,我们有一个数据迁移作业,它需要按顺序初始化模式A和B。我们通过定义多个SpringLiquibase来处理多个模式,每个模式对应一个SpringLiquibase,每个SpringLiquibase都有自己的数据源和主变更集。注意,通常在SpringBoot中,您不需要定义SpringLiquibase,因为它将检测单个数据源并使用该数据源自动配置SpringLiquibase 执行顺序似乎有所不同,这取决于作业是在IDE中本地运行,还是捆绑为单个JAR Spring启动应用程序 我们如何确保两

我们有一个数据迁移作业,它需要按顺序初始化模式A和B。我们通过定义多个SpringLiquibase来处理多个模式,每个模式对应一个SpringLiquibase,每个SpringLiquibase都有自己的数据源和主变更集。注意,通常在SpringBoot中,您不需要定义SpringLiquibase,因为它将检测单个数据源并使用该数据源自动配置SpringLiquibase

执行顺序似乎有所不同,这取决于作业是在IDE中本地运行,还是捆绑为单个JAR Spring启动应用程序

我们如何确保两次执行liquibase的顺序符合我们的要求


为什么顺序很重要:A包含一些表,而B包含引用A中表的视图。在尝试创建视图B之前,我们必须确保将A.*上的select授予B。某些视图。。。作为选择。。。从A.xyz开始,否则由于权限不足,B的创建将失败。

在对源代码进行了一些修改和深入研究之后,它变得非常简单

SpringLiquibase实现InitializingBean并在InitializingBean.afterPropertiesSet方法中执行Liquibase更新

Spring在完成初始化每个bean之后,对每个bean逐个调用此方法

因此,要强制执行特定的顺序,需要强制执行在Spring上下文中定义bean的顺序。最简单的方法是使用@DependsOn注释

因此,我们采取了如下措施:

@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
}

这不适用于spring boot,但如果您通过更改日志管理迁移,此解决方案将有所帮助。这假设您有不同模式的不同数据源

<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>

这与我们在没有@DependsOn的情况下所做的相同,但是是XML形式的。正如我在回答中所说,Liquibase执行是作为bean初始化的一部分完成的。当使用XML时,Spring是否会按照声明顺序初始化bean?这就解释了为什么这个答案会起作用。当使用Java annotation config时,情况并非如此,这就是为什么需要@DependsOn作为解决方案。spring可能会按照声明顺序初始化bean,但强制依赖迁移工作的实际情况取决于属性,这与您的答案中的DependsOn注释做了相同的事情。谢谢你的洞察力和你的回答。请原谅,当然是这样-我偶然回到这个答案,没有集中注意力