我正在考虑使用表触发器打电话给SQL CLR将事件放入队列或调用 Web 服务的对象。
虽然需要 SQLCLR 来进行 Web 服务调用,但您可能不需要 SQLCLR 来简单地将事件放入队列中。
长时间运行的触发器进程是否会阻止原始 INSERT 完成?
这不是“可以”的问题:它们绝对会,因为触发器是 DML 语句(或 DDL 触发器中的 DDL 语句,或 LOGON 触发器中的登录)事务的一部分。只要触发器正在执行,触发它的 DML 语句就会等待 COMMIT(这都是自动处理的)。
失败的触发进程是否会阻止原始 INSERT 完成?
这不是“可以”的问题:它们绝对会,因为触发器是事务(即 DML 语句)的一部分。事实上,如果你想基于某种逻辑取消一个DML操作,只需调用ROLLBACK;
.
TRIGGERS 是否在自己的线程上运行?
如果您询问它们是否与触发它们的 DML 语句异步运行,答案是不。根据上面的前两个答案,它们是同一交易的一部分。在 DML 语句完成初始工作(包括 CHECK/UNIQUE/等约束的验证)之前,触发器没有任何事情可做,并且在触发器完成之前 DML 语句无法完成。
这是愚蠢的尝试还是有更好的选择?
虽然直接进行 Web 服务调用比其他情况更适合某些情况,但这并不愚蠢。人们确实做到了这一点,并且取得了成功,但我相信也有不少人在条件不利的情况下试图做到这一点,结果却把事情弄得一团糟。我想说,如果 a) Web 服务位于本地 Intranet 上(即没有延迟,或几乎没有延迟),并且 b) Web 服务调用快速完成(或至少足够快地超时),那么您应该没问题去做这个。
然而,鉴于这将在触发器中,因此应该更加谨慎地处理。这让我想到了一些“更好的选择”,我在两天前在 DBA.StackExchange 上的一个几乎重复的问题中建议了这些:
我可以在与数据库实例不同的服务器上运行 CLR 存储过程吗? https://dba.stackexchange.com/questions/128283/can-i-run-a-clr-stored-procedure-on-a-different-server-than-the-database-instanc/128289#128289
并且,以下链接是 6 天前出现的另一个非常相似的问题(此处位于 S.O.),涉及 Web 服务调用。我对此问题的回答包含有关减少一般网络调用之间的争用的信息。这是您应该注意的事情,即使您采用队列方法并有一个由 SQL Server 代理作业启动的 T-SQL 存储过程,调用 SQLCLR 对象来执行 Web 服务调用。
SQL Server CLR 线程 https://stackoverflow.com/questions/35116558/sql-server-clr-threading/35116821#35116821