Java 使用Spring引导和多个模式进行Liquibase,如何指定执行顺序
我们有一个数据迁移作业,它需要按顺序初始化模式A和B。我们通过定义多个SpringLiquibase来处理多个模式,每个模式对应一个SpringLiquibase,每个SpringLiquibase都有自己的数据源和主变更集。注意,通常在SpringBoot中,您不需要定义SpringLiquibase,因为它将检测单个数据源并使用该数据源自动配置SpringLiquibase 执行顺序似乎有所不同,这取决于作业是在IDE中本地运行,还是捆绑为单个JAR 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包含引用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注释做了相同的事情。谢谢你的洞察力和你的回答。请原谅,当然是这样-我偶然回到这个答案,没有集中注意力