这是场景。
有多个微服务,每个微服务都使用Spring Boot运行。数据保存在一个公共数据库中,每个微服务都有其自己的架构。随着微服务表的不断发展,Liquibase用于维护。在该产品的全新安装中,Liquibase将在服务启动时创建新表。
出于各种原因,我们需要组合微服务。假设服务P(主要)和服务S(次要)将与一个模式下的所有表结合(在这种情况下为P)。要求之一是,组合微服务中的变更集应能够处理后端迁移。假设两个服务现在都在版本4中,而版本2的客户想要“升级”。在非组合服务的旧模型中,当服务P和S的版本4首次运行时,两个服务模式都将升级到V 4(假设V3和V4有所更改)。
合并服务需要处理相同的升级方案。我相信,如果我能找到一种从变更日志升级二级架构的方法,我就能解决。升级主数据库通常会发生,而不是问题。通常,更改日志由相应的databaseChangeLog表“驱动”运行。我之所以说“驱动”,是因为表中变更集的条目确定了在服务的成功调用中是否需要执行变更集。在使用自定义sql任务复制表之前,将需要增强新组合服务的更改日志以升级S的任何现有架构。我将现有的模式升级看作是一个不同的自定义任务,该任务设置了一个新的Liquibase环境,并针对其模式运行S的更改日志。下面的代码来自升级自定义任务的execute()方法,其中“ originalSchema”是需要升级的S的架构。
public void execute(Database database) throws CustomChangeException {
LOGGER.debug("Updating Schema " + originalSchema);
confirmationMessage = ""; // if there's an exception it'll visible in the log.
validateSettings();
JdbcConnection dbConn = (JdbcConnection) database.getConnection();
try {
Database db = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(dbConn);
String savedDefaultSchema = database.getDefaultSchemaName();
String savedLiquibaseSchema = database.getLiquibaseSchemaName();
database.setDefaultSchemaName(originalSchema);
ChangeLogHistoryServiceFactory savedCLHSFactory = ChangeLogHistoryServiceFactory.getInstance();
ChangeLogHistoryServiceFactory.reset();
Liquibase liquibase = new Liquibase(changeLogPath, new ClassLoaderResourceAccessor(), database);
liquibase.update(new Contexts(), new LabelExpression());
ChangeLogHistoryServiceFactory.setInstance(savedCLHSFactory);
database.setDefaultSchemaName(savedDefaultSchema);
confirmationMessage = String.format("UpgradeSchema has successfully run on schema %s using change log %s.", originalSchema, changeLogPath);
}
catch (DatabaseException de) {
throw new CustomChangeException(de);
}
catch (LiquibaseException le) {
throw new CustomChangeException(le);
}
}
我发现,如果不“重置” ChangeLogHistoryServiceFactory,它将使用组合服务的缓存变更日志表,该表用于“驱动”变更日志。 “服务”映射由ChangeLogHistoryServiceFactory维护,并且由于“ DataBase”(映射的键)不会更改,因此在新环境中不会返回相同的StandardChangeLogHistoryService。在ChangeLogHistoryServiceFactory上进行重置可以解决该问题。
作为Liquibase的相对新手(我已经使用“内置” Change对象编写了变更集,但从未尝试过自定义),我想就上述内容是否符合“最佳实践”,以运行Liquibase更改日志以影响更改集中的另一个架构。
我确实认识到上述内容不是线程安全的,但除非相关,否则我希望将其排除在讨论范围之外。