如何在Azure中实现关键部分

时间:2011-04-06 11:19:20

标签: multithreading azure queue

如何在Azure中的多个实例中实现关键部分?

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

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

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

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

注意:如果更新事务在2秒之前没有完成,那么我们应该将其重新命名并重新开始。

任何想法如何在Azure中的实例中实现关键部分将深受赞赏。

1 个答案:

答案 0 :(得分:0)

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

在这个特定的情况下,如果它听起来很重要,我会把它留给SQL服务器(它非常善于处理数据争用)。而不是让实例说“新的总值是X”,而是在SQL中调用存储过程,您只需传入此事务的值和要更新的帐户。像这样基本的东西:

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

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