用于事件驱动通信的 SQL CLR

本文关键字:SQL CLR 通信 事件驱动 用于 | 更新日期: 2023-09-27 18:33:28

在我工作的地方,他们使用长轮询技术来检测数据库中发生的事件。 虽然它有效...我想每个人都会同意轮询数据库不是最佳的。

我宁愿尝试某种推送技术或技术。 因此,我正在考虑使用表触发器来调用 SQL CLR 对象,该对象将事件放入队列或调用 Web 服务。

有很多

关于如何做到这一点的例子:

  • 从 SQL CLR 调用 Web 服务?
  • 如何从 SQL Server 存储过程调用 Web 服务
  • 在 CLR 集成中使用 Web 服务和 XML 序列化

但是,我有点担心这样做的智慧和表现。

所以我的问题是:

  • 长时间运行的触发进程是否会阻止原始 INSERT 完成?
  • 失败的触发过程会阻止原始插入完成吗?
  • 触发器是否在自己的线程上运行?
  • 这是愚蠢的尝试还是有更好的选择?

用于事件驱动通信的 SQL CLR

我正在考虑使用表触发器来调用 SQL CLR 对象,该对象将事件放入队列或调用 Web 服务。

虽然进行 Web 服务调用需要 SQLCLR,但您可能不需要 SQLCLR 来简单地将事件放入队列中。

长时间运行的触发进程是否会阻止原始 INSERT 完成?

这不是"可以"的问题:它们绝对会,因为触发器是作为 DML 语句的事务的一部分(如果是 DDL 触发器,则为 DDL 语句,如果是登录触发器,则为登录(。只要触发器正在执行,触发它的 DML 语句就会等待 COMMIT (这一切都是自动处理的(。

失败的触发过程会阻止原始插入完成吗?

这不是"可以"的问题:它们绝对会,因为触发器是 DML 语句事务的一部分。实际上,如果要根据某些逻辑取消DML操作,只需调用ROLLBACK;即可。

触发器是否在自己的线程上运行?

如果您询问它们是否异步运行到触发它们的 DML 语句,则不会。根据上述前两个答案,它们是同一交易的一部分。在 DML 语句完成初始工作(包括验证 CHECK/UNIQUE/etc 约束(之前,触发器没有任何操作,并且在触发器完成之前,DML 语句无法完成。

这是愚蠢的尝试还是有更好的选择?

这并不愚蠢,尽管执行直接 Web 服务调用更适合某些情况而不是其他情况。人们当然已经这样做了,并且已经取得了成功,但我相信,在条件不利的情况下,相当多的人也把试图这样做的事情弄得一团糟。我想说的是,如果 a( Web 服务位于本地 Intranet 上(即没有延迟,或者几乎没有延迟(,并且 b( Web 服务调用快速完成(或至少足够快地超时(,那么您应该可以这样做。

但是,鉴于这将在触发器中,因此应该更加谨慎地处理。这让我想到了一些"更好的选择",我在DBA上一个几乎重复的问题中提出了这些选择。StackExchange 就在 2 天前:

是否可以在与数据库实例不同的服务器上运行 CLR 存储过程?

而且,以下链接是另一个非常相似的问题(在 S.O.上(,仅在 6 天前出现,关于 Web 服务调用。我的回答是关于减少网络呼叫之间争用的信息。这是您应该注意的事情,即使您采用队列方法并具有由 SQL Server 代理作业启动的 T-SQL 存储过程,也调用 SQLCLR 对象来执行 Web 服务调用。

SQL Server CLR 线程