【问题标题】:How to implement critical section in Azure如何在 Azure 中实现临界区
【发布时间】:2011-07-30 17:51:45
【问题描述】:

如何在 Azure 中跨多个实例实现临界区?

我们正在 Azure 上实施支付系统。 在 SQL-azure 中更新帐户余额时,我们需要确保该值 100% 正确。 但是我们有多个 webrole 正在运行,因此它们将能够同时处理来自不同客户的两个请求,这可能会更新单个产品的当前余额。因此,两个实例可以同时从数据库中读取旧金额,然后都将购买添加到旧值中,并且都将新金额存储在数据库中。首先保存的人将覆盖其更改。 :-(

因此,我们需要围绕数据库中帐户余额的所有更新实施关键部分。但是如何在 Azure 中做到这一点?指南建议使用 Azure 存储队列进行进程间通信。 :-) 它们确保消息在被处理之前不会从队列中删除。 即使一个进程崩溃了,那么我们确信该消息将被下一个进程处理。 (作为 Azure 保证在出现问题时启动新进程)

我考虑过运行一个单例工作者角色来为队列中的请求提供服务。但是,当您不并行运行至少两个实例时,Azure 不能保证良好的正常运行时间。此外,当我将新版本部署到 Azure 时,我必须先停止正在运行的实例,然后才能启动新版本。我们的应用程序不能接受“临界区工作者角色”没有在 2 秒内处理队列中的消息。

因此,我们需要多个工作人员角色来保证足够短的停机时间。在这种情况下,我们又回到了在 Azure 中跨多个实例实现关键部分的相同问题。

注意:如果更新事务在 2 秒之前还没有完成,那么我们应该重新设置它并重新开始。

任何关于如何在 Azure 中跨实例实现关键部分的想法将不胜感激。

【问题讨论】:

  • 有人建议使用 SQL-Azure 作为锁提供程序,如下所示: [ UPDATE MyTable SET synchCol = @time FROM MyTable WHERE synchCol IS NULL or DATEDIFF(second, synchCol, @time) > 2 ]如果 SQL-azure 保证此更新语句是原子操作是正确的,那么我想它可以工作....

标签: multithreading azure queue


【解决方案1】:

跨实例进行同步是一项复杂的任务,最好尝试考虑问题,这样您就不必这样做了。

在这种特定情况下,如果它像听起来那样重要,我会将其留给 SQL Server(它非常擅长处理数据争用)。与其让实例说“新的总值是 X”,不如在 SQL 中调用一个存储过程,您只需在其中传递此事务的值和要更新的帐户。像这样基本的东西:

UPDATE Account
SET
  AccountBalance = AccountBalance + @TransactionValue
WHERE
  AccountId = @AccountId

如果您需要更新多个表,请在同一个存储过程中完成所有操作并将其包装在 SQL 事务中。我知道它没有使用任何性感的技术或框架,但它比我能想到的任何替代方案都简单得多。

【讨论】:

  • 感谢您的评论。是的,我实际上选择了这条路线。我发现你甚至可以这样做:更新 Account set @balance = AccountBalance = AccountBalance + @TransactionValue 其中 AccountID = @AccountID。据我所知,当我在一个事务中包装几个更新和语句时,这些行会被锁定,直到事务提交或失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多