我正在考虑使用 表触发器 来调用 SQL CLR 对象,该对象要么将事件放入队列中,要么调用 Web 服务。
虽然需要 SQLCLR 来进行 Web 服务调用,但您可能不需要 SQLCLR 来简单地将事件放入队列。
长时间运行的触发器进程会阻止原始 INSERT 完成吗?
这不是“可以”的问题:他们绝对会,因为触发器是作为 DML 语句的事务的一部分(或者在 DDL 触发器的情况下是 DDL 语句,或者在登录的情况下是登录扳机)。只要触发器正在执行,触发它的 DML 语句就在等待 COMMIT(这都是自动处理的)。
失败的触发器进程会阻止原始 INSERT 完成吗?
这不是“可以”的问题:他们绝对会,因为触发器是作为 DML 语句的事务的一部分。事实上,如果你想基于某种逻辑取消一个 DML 操作,只需调用ROLLBACK;即可。
TRIGGERS 是否在自己的线程上运行?
如果您询问它们是否与触发它们的 DML 语句异步运行,则不会。根据上面的前两个答案,它们是同一事务的一部分。在 DML 语句完成初始工作(包括验证 CHECK / UNIQUE / 等约束)之前,触发器没有任何事情要做,并且 DML 语句在触发器完成之前无法完成。
这是愚蠢的尝试还是有更好的选择?
并不愚蠢,尽管直接调用 Web 服务更适合某些情况而不是其他情况。人们当然已经做到了这一点,并且在这方面取得了成功,但我敢肯定,在条件不利的情况下,也有相当多的人试图做到这一点,把事情搞得一团糟。我想说的是,如果 a) Web Service 位于本地 Intranet 上(即没有延迟,或者几乎没有),并且 b) Web Service 调用很快完成(或者至少超时足够快),那么你应该没问题这样做。
但是,鉴于这将在触发器中,因此应该更加谨慎地处理。这让我想到了一些“更好的选择”,我在两天前的 DBA.StackExchange 上提出了一个几乎重复的问题:
Can I run a CLR Stored Procedure on a different server than the database instance?
而且,以下链接是 6 天前出现的另一个非常相似的问题(在 S.O. 上),关于 Web 服务调用。我对此的回答提供了有关减少一般网络呼叫之间争用的信息。这是您应该注意的事情,即使您采用队列方法并拥有由 SQL Server 代理作业启动的 T-SQL 存储过程,调用 SQLCLR 对象来执行 Web 服务调用。
SQL Server CLR Threading