.net 原子性:数据库事务和Windows Azure 背景

.net 原子性:数据库事务和Windows Azure 背景,.net,azure,distributed-transactions,c#-5.0,.net,Azure,Distributed Transactions,C# 5.0,有一个消息队列域。此域可能与某些消息队列技术配合使用。在这种特殊情况下,它绑定到WindowsAzure服务总线 某些项目具有注册Windows Azure服务总线主题(基本上是消息队列)的操作 注册新消息队列意味着: 启动域事务(即数据库事务) 添加带有一些相关信息的消息队列域对象(例如,哪个用户注册了它,或者整个消息队列属于哪个应用程序) 使用控制反转来处理消息队列服务器中的实际队列注册(在这种情况下,它将针对WindowsAzure服务总线) 若并没有任何问题,域事务将被提交,关联的域对象

有一个消息队列域。此域可能与某些消息队列技术配合使用。在这种特殊情况下,它绑定到WindowsAzure服务总线

某些项目具有注册Windows Azure服务总线主题(基本上是消息队列)的操作

注册新消息队列意味着:

  • 启动域事务(即数据库事务)
  • 添加带有一些相关信息的消息队列域对象(例如,哪个用户注册了它,或者整个消息队列属于哪个应用程序)
  • 使用控制反转来处理消息队列服务器中的实际队列注册(在这种情况下,它将针对WindowsAzure服务总线)
  • 若并没有任何问题,域事务将被提交,关联的域对象将被持久化或更新
  • 如果域事务成功结束,并且Windows Azure服务总线主题注册工作正常,则它应该可以正常工作

    问题 但是,如果域事务成功结束,但Windows Azure服务总线无法注册主题(又名消息队列),会发生什么情况?

    是的,您的域已断开

    如果在域事务开始之前注册Windows Azure服务总线主题,会发生什么情况?好吧,如果一切顺利,没问题。但现在问题已经颠倒过来了:如果Windows Azure服务总线主题正确注册,但随后域事务失败,会发生什么情况?

    对,第二种情况比第一种情况好,因为操作注册了一个无用的消息队列,但域不知道它。现在的主要问题是,不确定数量的事务可能会失败,而未知数量的消息队列可能会白白存在

    试想一下,如果这是一项严肃而大型的业务服务:大量无用的消息队列,系统管理员(一个人)每月都会删除无用的消息队列

    那么现在的问题是什么? 由于我发现拥有无用的消息队列比拥有断开的域更好,因此我选择了继续这样做,但是…Microsoft Azure是否有任何类型的分布式事务机制,以便在原子事务中包括任何远程对象创建,包括其他特定于域的操作?如果不是,很遗憾,我认为这是实际情况,您将如何解决这个问题?

    注: 我在寻找这样的东西,因为我真的不喜欢有一个领域根本不能处理它的用例。我更愿意避免这种情况,让域正常工作并控制一切

    一些有趣的链接。。。 我发现了一些关于这个主题的有趣链接:


    您可以通过使用状态来解决此问题,而无需进行事务处理。设想以下工作流:

  • 注册域并将其状态设置为挂起
  • 创建服务总线主题
  • 将域的状态设置为活动
  • 然后,您可以使用一个小流程来检查挂起的域:

    • 如果域挂起但主题存在,请将状态设置为“活动”(在这种情况下,步骤3可能失败)
    • 如果域挂起但主题不存在,请尝试重新创建该主题或向可以手动检查正在发生的情况的人员发送警报
    有了重试策略(如黄玉),99%的请求都不会出现任何问题。但无论什么时候出了问题,都会自动修复,如果无法修复,则会升级为人工干预


    另一种选择可能类似于Clemens的博客文章,在SQL Azure中使用发件箱表,并在注册域的同一事务中写入该发件箱表。

    这是一个好的观点。我喜欢你关于各州的建议。我目前的解决方案是:1)注册队列时,在提交域事务之前执行服务总线部分;2)取消注册队列时,在服务总线部分之前执行并提交域部分。这是一个很好的保证,因为域应该始终保持一致。(在下一篇评论中继续)另外,我喜欢你的方法,因为只要想象一下域部分处于挂起状态。用户界面将有一个名为“重试”的按钮,这样可以再次使用已创建的域部件来执行Windows Azure部件。谢谢我将等待其他观点将任何答案标记为所选答案,但我将整合状态概念。