原子性:数据库事务和Windows Azure

时间:2012-11-20 09:13:18

标签: .net azure distributed-transactions c#-5.0

背景

有一个消息队列域。此域可能适用于某些消息队列技术。在这种特殊情况下,它绑定到 Windows Azure Service Bus

某个项目有一个注册 Windows Azure Service Bus 主题的操作(基本上是一个消息队列)。

注册新的消息队列意味着:

  1. 启动域事务(即数据库事务)。
  2. 添加带有一些关联信息的消息队列域对象(例如用户注册它或者属于整个消息队列的应用程序)。
  3. 使用控制反转来处理邮件队列服务器中的实际队列注册(在这种情况下,它将针对Windows Azure Service Bus发生)。
  4. 如果没有出错,域事务将被调整,关联的域对象将被保留或更新。
  5. 如果域事务成功结束且 Windows Azure Service Bus 主题注册工作正常

    ,则应该可以正常运行。

    问题

    但是如果域事务成功结束但 Windows Azure Service Bus 无法注册主题 - 也就是消息队列 - 会发生什么?

    是的,你的网域已经破了

    如果您在域事务启动之前进行 Windows Azure Service Bus 主题注册会发生什么?好吧,如果一切顺利,没问题。但现在问题已经被颠倒了:如果 Windows Azure Service Bus 主题被正确注册但后来域事务失败会怎样?

    是的,第二种情况比第一种情况更好,因为操作已经注册了一个无用的消息队列,但域名不知道它。现在主要的问题是,不确定数量的事务可能会失败,并且未知数量的消息队列将一无所获。

    想象一下,如果这是一个严肃的大型商业服务:许多无用的消息队列和系统管理员(人)每月删除无用的消息队列

    那么 - 现在的问题 - ?

    由于我发现选择无用的消息队列比拥有破坏的域更好,我选择以这种方式继续前进,但是...... 在Windows Azure中有任何类型的分布式事务机制为了在原子事务中包含任何远程对象创建,包括其他特定于域的操作?如果不是 - 遗憾的是我认为这是实际情况 - ,您将如何解决这种情况?

    注意:

    我正在寻找类似这样的东西,因为我真的不喜欢有一个根本无法处理其用例的域名。我更愿意避免这种情况,让域名正常运行并控制所有内容

    一些有趣的链接......

    我发现了一些有关此主题的有趣链接:

    http://blogs.msdn.com/b/clemensv/archive/2012/07/30/transactions-in-windows-azure-with-service-bus-an-email-discussion.aspx

1 个答案:

答案 0 :(得分:6)

您可以使用状态在没有交易的情况下解决此问题。想象一下以下工作流程:

  1. 注册域名并将其状态设置为待处理
  2. 创建服务总线主题
  3. 将域的状态设置为活动
  4. 然后,您可以使用一个小流程来检查待处理域:

    • 如果某个域处于待处理状态但主题存在,请将状态设置为活动(在这种情况下,步骤3可能会失败)。
    • 如果某个域处于待处理状态但该主题不存在,请尝试重新创建该主题,或向可以手动检查所发生情况的人发送提醒

    如果采用重试策略(如TOPAZ),99%的请求都不会出现任何问题。但是每当出现问题时,它会自动修复,或者如果无法修复,它将升级为人为干预。

    替代方案就像在Clemens的博客文章中那样,您在SQL Azure中使用发件箱表,并在注册域的同一事务中写入此发件箱表。