为消息传递目的而使用SQL Server数据事件

mit*_*tix 11 c# sql-server-2005 rabbitmq

在我们的组织中,我们有一个SQL Server 2005数据库和相当数量的数据库客户端:网站(php,zope,asp.net),富客户端(传统狐狸专业版).现在我们需要将核心数据库中的某些事件与其他系统(MongoDb,LDAP和其他系统)一起传递.消息传递范式似乎非常能够解决这类问题.所以我们决定使用RabbitMQ代理作为中间件.

最初从数据库中消耗事件的问题似乎只有两种可能的解决方案:

  1. 轮询数据库以查找传出消息并将其传递给消息代理.
  2. 在某些表上使用触发器将消息传递到同一台计算机上的代理.

由于涉及定期执行sql时出现的延迟问题,我不喜欢第一个想法.

但基于事件的触发方法存在一个目前无法解决的问题.考虑这种情况:

  1. 将一行插入表中.
  2. 触发器触发并发送消息(使用C#编写的CLR存储过程)

除非回滚写入数据的事务,否则一切正常.在这种情况下数据将是一致的,但该消息已被发送,并因为在写入数据库日志,而不是在交易发生时的瞬间触发火灾承诺不能被回滚(这是一个RDBMS的正确行为) .

我现在意识到我要求太多的触发器,它们不适合处理数据以外的任务.

所以我的问题是:

  1. 有没有人设法使用触发器提取数据事件?
  2. 您可以提供哪些其他消耗数据事件的方法?
  3. 在我的情况下,查询通知(建立在Service Broker之上)是否合适?

提前致谢!

Rem*_*anu 11

为了避免出现明显不合适的等式:查询通知不是正确的技术,因为它旨在解决相对稳定数据的缓存失效问题.使用QN,您只会知道该表已更改,但您无法知道更改了什么.

感谢您找出触发SQLCRL的触发器的原因:回滚时打破了一致性.

那么,什么工作?考虑一下:BizTalk Server.换句话说,围绕这个问题空间建立了整个业务,解决方案远非微不足道(否则没有人会购买此类产品).

遵循一些原则,你可以走得很远:

  • 解耦.基于事件的触发器是可以的,但不要从触发器发送消息.除了回滚的一致性问题之外,还存在延迟问题,即现在每个DML操作都在等待外部API调用(RabbitMQ发送)和外部API调用失败的可用性问题(如果RabbitMQ不可用,则您的数据库不可用).解决方案是让触发器使用普通表作为队列,触发器将在本地数据库队列中排队消息(即将插入此表),并且外部进程将通过使消息出列来服务此队列(即从表)并将它们转发给RabbitMQ.这将事务与RabbitMQ操作分离(外部进程能够看到仅当原始xact提交时才显示消息,但成本是一些明显增加的延迟(涉及额外的跳,本地表充当队列).
  • 幂等性.由于RabbitMQ无法使用数据库注册分布式事务,因此无法保证数据库操作的原子性(本地表充当队列的队列)和RabbitMQ操作(发送).当另一个失败时,任何一个都可以成功,并且没有办法解决它与显式分布式事务注册支持.这意味着应用程序每隔一段时间就会发送一次重复的消息(通常情况下,由于某种原因,事情已经变坏).快速抬头:注册明确的"确认"消息并发送序列号是一场失败的战斗,因为你很快就会发现你在消息传递之上重新发明了TCP,这条路是用尸体铺设的.
  • 宽容.出于与上述项目相同的原因,每隔一段时间,您认为发送的消息将永远不会成功.同样,这导致的损害完全取决于业务.问题不在于如何防止这种情况(几乎不可能......),而是如何检测这种情况,以及该如何应对.我害怕,没有银弹.

你在传递Service Broker时提到了(为查询通知提供动力的事实是它的最少的interestign方面...).作为SQL Server中内置的消息传递平台,它提供了完全一次按顺序的交付保证并且完全交易,它将解决所有上述痛点(您可以SEND从触发器中解决,不受惩罚,您可以使用激活为了解决延迟问题,你永远不会看到重复或丢失的消息,有明确的错误语义)和其他一些我之前没有提到的痛点(备份/恢复的一致性,因为数据和消息是相同的存储单元 - 数据库,HA/DR故障转移的一致性,因为SSB支持数据库镜像和群集等).然而,退回的是SSB只能与另一个SSB服务通信,换句话说,它只能用于在两个(或更多)SQL Server实例之间交换消息.任何其他用途都要求各方使用SQL Server来交换消息.但是,如果您的端点都是SQL Server,那么请考虑使用Service Broker进行一些大规模部署.请注意,像php或asp.net这样的端点可以被认为是SQL Server端点,它们只是在数据库API之上编程层,不同的端点就是说,需要将手机设备(电话)的消息直接发送到数据库(并且那些99%的时间都去了!通过Web服务,这意味着他们最终可以访问SQL Server).另一个考虑因素是SSB适用于吞吐量和可靠交付,而不是低延迟.例如,绝对不是用于在HTTP Web请求中获取响应的技术.是用于提交处理由Web请求触发的内容的技术.