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

Mat*_*zer 3 .net distributed-transactions azure c#-5.0

背景

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

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

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

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

在背景之上,如果域事务成功结束并且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

San*_*tia 6

您可以通过使用解决这个无交易状态.想象一下以下工作流程:

  1. 注册域并将其状态设置为挂起
  2. 创建服务总线主题
  3. 将域的状态设置为活动状态

然后,您可以使用一个小进程来检查挂起的域:

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

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

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