我们有一个数据迁移作业,需要按此顺序初始化模式A
和B
。我们通过定义多个SpringLiquibase
处理多个模式,每个模式一个,每个都有自己的数据源和自己的主变更集。 (请注意,通常在Spring Boot中,您不需要定义SpringLiquibase,因为它将检测到一个数据源并使用该数据源为您自动配置SpringLiquibase。)
执行顺序似乎有所不同,具体取决于作业是在IDE中本地运行还是作为单个JAR Spring Boot应用程序捆绑在一起。
我们如何确保liquibase的两次执行按我们想要的顺序进行?
(为什么顺序很重要:A
包含一些表,而B
包含引用A
中的表的视图。我们必须确保在grant select on A.* to B
之前尝试create view B.some_view (...) as select ... from A.xyz
,否则由于特权不足而无法创建B。)
答案 0 :(得分:3)
经过一番摸索并深入研究了源代码,事实证明它非常简单。
SpringLiquibase实现InitializingBean
,并在InitializingBean.afterPropertiesSet()
方法内执行Liquibase更新。
在完成每个bean的初始化之后,Spring在每个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
}
答案 1 :(得分:1)
这不是用于春季启动,但如果您通过更改日志管理迁移,则此解决方法将有所帮助。假设您具有用于不同模式的不同数据源。
<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>