当前位置: 首页 > 知识库问答 >
问题:

如何在多模式MSSQLServer环境中使用Flyway?

齐振
2023-03-14

我们有一个使用“多模式”策略的多租户SaaS应用程序,即每个客户在同一数据库实例中都有专用模式。我们使用MSSQLServer作为数据库,通过SQLServer“用户”的“默认模式”设置在模式之间切换。例如,客户A、B和C在SQL Server中的配置如下:

  • 客户A:user_A默认模式schema_A
  • 客户B:user_B默认模式schema_B
  • 客户C:user_C具有默认模式schema_C…等等。

在我们的应用程序中,我们通过在每次查询之前执行以下 SQL,在连接上设置 SQL Server“用户”,将数据源连接切换为指向每个客户的正确架构:

EXECUTE AS USER = 'user_A';

当我们试图使用Flyway以全局方式管理模式版本的状态时,这给我们带来了一些问题。由于flyway的模式支持只接受一个模式名称列表,这对MSSQLServer不起作用。Flyway根据DataSource配置提供的用户的默认模式执行迁移;在SQL Server的情况下,“用户”需要根据客户/模式而变化。

理想情况下,我们将有一个像FlywayCallback.beforeEachSchemaMigrate(Connection)这样的回调,它将允许我们通过在每个架构的每次迁移之前执行“以用户身份执行”语句来设置每个架构所需的用户上下文。不知道为什么没有那个挂钩?

flyway的另一个缺点是使用模式列表中第一个模式的约定,作为保存< code>schema_version表的模式。这在基于SQL Server的多租户环境中是不可取的。因为我们不能假设包含< code>schema_version表的模式也是真实的客户模式。请记住,在像我们这样的SaaS应用程序中,每个租户/客户的模式是动态创建/销毁的。当用户注册时,供应过程的一部分基于一些约定创建新的模式。所以模式列表对我们来说是动态的。

理想情况下,我们可以告诉 Flyway 使用给定的架构来创建schema_version表,而无需尝试在该架构上运行迁移。通常,这将是 dbo 架构(这是 SQL 服务器中的默认架构)。我们使用 dbo 架构来保存所有租户中本质上的全局表,schema_version将被视为全局表。

因此,最终在成功迁移后,我们的数据库应该如下所示:

 - dbo.schema_version
 - schema_A.my_tables
 - schema_B.my_tables
 - schema_C.my_tables

所有上述模式都处于相同的状态,由dbo.schema_version表指示和控制。

这目前是否可行?

共有1个答案

史高阳
2023-03-14

你必须以不同的方式处理这个问题。不是为每个人执行一次 Flyway,而是为每个架构执行一次。可以将 Flyway 包装在一个循环中,并在每次迭代中为一个租户提供正确的配置。最终,每个租户都有一个schema_version表,但它们都可以单独命名,并且仍存在于 dbo 架构中。

 类似资料:
  • 我正在使用多线程执行插入操作。我使用了带注释的方法,我的方法是注释。但我无法执行插入操作,导致出现以下异常。 异常线程"Thread-21"javax.persistence.Transaction必需异常:在org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96)在sun.reflect.Native

  • 问题内容: 我正在开发一个项目,在该项目中,我需要对正在运行的服务器进行HTTP URL调用,该服务器将响应作为JSON字符串返回。 下面是我的主要代码,它使用和- 下面是我的类,它实现接口并使用… 现在我有下面的代码在另一大类它调用的方法类顺序- 所以我的问题是在这里应该是静态的,就像我正确看到的一样,我正在为每个请求重新创建整个连接池,而我猜这不是正确的方法。 注意: 如果我将RestTemp

  • 现在,他提出的下一个问题是为多线程环境编写单例类。然后,我写了双重检查单例类。 然后,他反对使用和双重检查,并说这是没用的。为什么要检查两次,为什么要使用synchronized?我试着用多种方案说服他。但是,他没有。 后来,我在家里尝试了下面的代码,在那里我使用了带有多个线程的简单的单例类。 那么,问题是,在多线程环境中是否有必要使用或/和双重检查方法?似乎我的第一个代码本身(没有添加任何额外的

  • 我正在做一个项目,在这个项目中,我需要对运行

  • 我试图了解Google App Engine的文件。 我们有一个普通的web应用程序,有前端和后端。我们还有一个开发和生产环境。这两种环境在GAE上都有两种服务——和,后者是后端。 我们有一个普通的web应用程序,有前端和后端。我们还有一个开发和生产环境。我们在GAE上有两个服务——前端和默认,后者是后端。我们有两个关于GAE-(这是我们的开发环境)和(这是我们的生产环境)的项目。登台环境是从前端

  • 问题内容: 情况如下: 我有一个使用SP作为数据集的SSRS报告。SP创建一个临时表,在其中插入一堆数据,然后选择将其退回以供SSRS报告。挺直截了当的。 问题: 如果多个用户在选择了不同参数的情况下运行报表,SP创建的临时表是否会与tempdb冲突,并可能无法返回预期的数据集? 问题答案: 很有可能不会。如果将临时表定义为或,那么您是安全的,因为这类临时表只能由创建连接访问,并且仅在存储过程执行