C# 使用SQL Server数据事件进行消息传递
在我们的组织中,我们有一个SQLServer2005数据库和大量的数据库客户端:网站(php、zope、asp.net)、富客户端(legacy fox pro)。现在我们需要将核心数据库中的某些事件传递给其他系统(MongoDb、LDAP和其他系统)。消息传递范式似乎很有能力解决这类问题。因此,我们决定使用RabbitMQ代理作为中间件 起初,从数据库中消费事件的问题似乎只有两种可能的解决方案:C# 使用SQL Server数据事件进行消息传递,c#,sql-server-2005,rabbitmq,C#,Sql Server 2005,Rabbitmq,在我们的组织中,我们有一个SQLServer2005数据库和大量的数据库客户端:网站(php、zope、asp.net)、富客户端(legacy fox pro)。现在我们需要将核心数据库中的某些事件传递给其他系统(MongoDb、LDAP和其他系统)。消息传递范式似乎很有能力解决这类问题。因此,我们决定使用RabbitMQ代理作为中间件 起初,从数据库中消费事件的问题似乎只有两种可能的解决方案: 轮询数据库中传出的消息,并将它们传递给消息代理 在某些表上使用触发器将消息传递给同一台机器上的代理
提前谢谢 以免首先从等式中剔除明显的不匹配:查询通知技术不适合这种情况,因为它旨在解决相对稳定数据的缓存失效问题。使用QN,您只能知道表已更改,但无法知道更改了什么 感谢您找出了调用SQLCRL的触发器不起作用的原因:回滚时一致性被破坏 那么什么有效呢?想想看:换句话说,整个业务都围绕着这个问题空间展开,而解决方案绝不是微不足道的(否则没有人会购买这样的产品) 通过遵循以下几个原则,您可以走得更远:
- 解耦。基于事件的触发器可以,但不从触发器发送消息。除了回滚时的一致性问题外,您还存在让每个DML操作现在等待外部API调用(RabbitMQ发送)的延迟问题,以及外部API调用失败的可用性问题(如果RabbitMQ不可用,则您的DB不可用)。解决方案是让触发器使用普通触发器,触发器将消息排入本地db队列(即插入此表),外部进程将通过将消息移出队列(即从表中删除)并将其转发到RabbitMQ来服务此队列。这将事务与RabbitMQ操作分离(只有在原始xact提交时,外部进程才能看到消息),但代价是明显增加了延迟(涉及额外的跃点,本地表充当队列)
- 幂等性。由于RabbitMQ无法注册数据库的分布式事务,因此无法保证DB操作(从本地表中作为队列出列)和RabbitMQ操作(发送)的原子性。当另一个失败时,任何一个都可以成功,没有显式的分布式事务注册支持,根本没有办法解决。这意味着应用程序每隔一段时间就会发送重复的消息(通常是在某些原因导致情况恶化时)。快速提醒:加入明确的“确认”消息和发送序列号的行为是一场失败的战斗,因为你很快就会发现,你正在消息的基础上重新发明TCP,这条路是由身体铺就的
- 公差。出于与上述项目相同的原因,有时您认为发送的消息永远不会成功。同样,这造成的损害完全取决于业务。问题不是如何防止这种情况(几乎不可能…),而是如何检测这种情况,以及如何处理。恐怕没有银弹