2013-07-21 80 views
1

我有两个Azure网站设置 - 一个为客户端应用程序提供无数据库服务,另一个提供数据库和WebApi解决方案,客户端从中获取数据。Azure网站迁移和并发

我即将向数据库添加一个新表,并使用我仅计划运行一次的临时Seed方法填充数据。但我不确定最好的方法是什么。

现在我将数据库初始化程序设置为MigrateDatabaseToLatestVersion,我已经多次在本地测试此更新。一切似乎都不错,但更新/种子方法需要大约6分钟才能运行。我在迁移时遇到一些关于并发性的问题:

当某人在这个6分钟窗口中更新业务逻辑和表时正在对数据库执行CRUD操作时会发生什么?我的意思是 - 从VS打出“发布”到实际部署新位之间的时间。如果种子方法修改了另一个表中的每个条目,并且用户添加了一些不受此重要更新命中的中间种子数据?我应该锁定网站,以防万一(远离理想......)?

关于这个过程的任何一般指导都很棒。

回答

1

像创建一个新表或添加新列的操作应该只对性能产生最小的影响并且是透明的,特别是当应用程序应用推荐的处理瞬态故障的模式时(例如通过利用Enterprise Library)。

大量更新或重新索引可能会导致争用并影响应用程序的性能甚至导致错误。根据情况,瞬态故障处理也可以解决这个问题。

对正在升级的数据进行并行修改可能会导致难以处理的问题。这些都是一些可能的方案:

维护窗口

最简单,最安全的方法是将应用程序脱机,备份数据库,升级数据库,更新应用,测试和使应用程序重新联机。

只读模式

此方法可避免使应用程序完全不可用,通过网上保持,但禁止改变数据库的任何功能。用户仍然可以在应用程序更新时查询和查看数据。

分阶段升级

这种方法是基于更改了数据库结构和数据,并在应用程序代码的精心策划序列,以便在任何给定阶段的应用程序版本,在线与当前兼容数据库结构。

例如,假设我们需要在客户记录中引入“上次购买日期”字段。可以使用此序列:

  1. 将新字段添加到数据库中的客户记录(不更新应用程序)。将新的字段默认值设置为NULL。
  2. 更新应用程序,以便对于每次新的销售,上次购买日期更新。对于旧销售,字段保持不变,此时应用程序不查询或显示新字段。
  3. 在数据库上执行一个批处理作业,为所有仍然为NULL的客户更新此字段。可以在更新之间引入延迟,以便系统不会过载。
  4. 更新应用程序以开始查询并显示新信息。

这种方法有几种变化,例如Zero-Downtime Database Deployment中描述的“扩展脚本”和“收缩脚本”的概念。这可以与feature toggles一起使用,以随着升级阶段的执行而改变应用程序的行为。

可以将新列添加到记录以表明它们已被转换。应用程序逻辑可以适用于同时处理旧版本和新版本中的记录。

实体框架可能会在选项中施加一些额外的限制,因为它代表应用程序生成SQL语句,因此在规划阶段时必须考虑这一点。

临时环境

更改生产数据库结构和执行质量数据的变化是有风险的业务,特别是当它必须在一个特定的顺序进行,而正在进入并改变数据的用户。你的选择来回复错误可能受到严重限制。

在执行生产环境的升级过程之前,有必要在单独的临时环境中进行大量测试和模拟。

1

我同意费尔南多的维护窗口的想法。但是,这是我给你的问题的方法。

  1. 确保你的数据库做任何事情之前备份(我假设它的SQL Azure中)
  2. 提出了一个维护页面上的客户端应用程序
  3. 运行通过Visual Studio中的迁移到你的数据库(我假设您通过控制台执行此操作)或单元测试
  4. 发布网站/ web api网站
  5. 验证您的更改。

最重要的是通过Entity Framework使用种子方法,它很容易让它错误,没有一个适当的备份,而运行反Prod你可以让你自己陷入麻烦真快。我可能会首先运行它通过测试数据库/环境(如果有的话)来验证你想要发生的事情。