【问题标题】:SQLCLR trigger vs Windows service. When is it appropriate to use SQLCLR?SQLCLR 触发器与 Windows 服务。什么时候适合使用 SQLCLR?
【发布时间】:2010-10-18 20:31:49
【问题描述】:

我们有一个带有 SQL Server 2005 后端的 .NET 电子商务应用程序。新订单需要一定的“后处理”。这些任务包括发送电子邮件、创建文件、将文件上传到 FTP 服务器以及对 WCF 数据服务执行 CRUD 操作。执行所有这些任务的代码已经作为几个 .NET 类库存在。

我的团队正在争论的是将这段代码放在哪里。我编写了一个简单的 Windows 服务,它定期轮询数据库,并在检测到数据库中的新事务(基于标志)时,它会执行必要的操作并记录任何错误。已提出的替代方案是将触发处理的 SQLCLR INSERT 触发器。

我知道在 SQLCLR 中完成上述大部分任务(全部?)在技术上是可行的——我什至发现了许多文章解释了如何从 SQLCLR 中使用 Web 服务,显然人们正在这样做。但我仍然犹豫不决。 SQLCLR 曾经打算用于这种事情吗?如果没有,实际的缺点是什么?至于 SQLCLR 触发器相对于 Windows 服务的潜在好处,我只能看到一个:更少的数据库流量。我们预计最初​​的交易量很轻,因此 windows 服务会产生一些“浪费”的流量。但是服务和数据库在同一个盒子里,所以它甚至不影响网络,只影响内部服务器资源。

最后,第三种可能性是使用 SQLCLR 触发器在文件系统上保存一个简单的令牌,并使用 Windows 服务中的 FileSystemWatcher(而不是 Timer)来根据需要执行任务。

请分享您对这些不同方法的权衡取舍的想法,或提出更好的替代方案。

【问题讨论】:

  • 我在 MSDN 杂志中找到了以下文章:bit.ly/cyxEbw。它很好地解决了 T-SQL 和 SQL CLR 之间的权衡问题,但不幸的是它并没有解决我的问题。

标签: .net sql-server windows-services wcf-data-services sqlclr


【解决方案1】:

在查看类似流程时,我们考虑了一些事情。

  1. 当依赖系统(邮件、ftp)不可用时会发生什么?
  2. 如何恢复故障?
  3. 如果我们处于失败状态,新记录会发生什么情况。即使我们知道系统已关闭,他们是否也会尝试进行后期处理?
  4. 支持生产系统的人员具备哪些技能?
  5. 如何监控此过程?
  6. 后处理系统是否在处理时消耗主系统的资源?您将如何将它们分开?
  7. 是否支持故障转移?

我们选择使用 Windows 服务是因为它为那些支持系统的人(那些愿意花更多时间在 serverfault 而不是 stackoverflow 上的人)提供了最佳体验。由于它有一个既定的方法来停止和启动服务、监控、集群支持、易于将处理拆分到多台机器、与事件日志集成等。

【讨论】:

  • +1 因为仅第 1 项就足以解决任何基于触发器的解决方案。剩下的只是为了额外的功劳;)
  • 一个非常好的观点。即使我们继续使用数据库标志并检查每次插入时的所有记录,这也是一个漏洞,因为在纯 CLR 触发场景中,在下一个事务进入之前不会重新尝试后处理,这可能需要几天时间。
【解决方案2】:

SQL CLR 是为某些事情而设计的——这不是其中之一,将这类东西放在 INSERT 触发器中真的会让婴儿耶稣哭泣。

一个潜在的解决方案是使用查询通知来减轻服务和数据库之间的负载 - 可以通过允许通过 UDP 或类似的轻量级“ping”服务来采取另一条路线 - 这意味着您不会在 INSERTS 上导致大量发生(因此您不会长时间锁定基础表)。

【讨论】:

  • 到目前为止,您确认了我的怀疑,即 SQL CLR 不适合我们正在进行的那种处理。你能详细解释一下它的邪恶之处吗?它会导致 SQL Server 宕机吗?怎么样?
  • 它不会让 SQL Server 宕机(除非你创建一个 UNSAFE 程序集来做你想做的事,然后设法破坏进程空间)——但你很容易导致锁被持有一段时间通过创建一个运行很长时间的触发器,比他们需要的时间长得多。如果你在一个 UNSAFE 程序集中做事,那么所有的赌注都没有了——SQL Server 中的 CLR 中的编程模型限制是有原因的——我不会愚蠢到假装我知道所有的来龙去脉,但他们一般应该尊重...
  • +1 表示“让婴儿耶稣哭泣”并推荐查询通知作为数据库更改机制。
  • @Antony:因为 SQLCLR 托管在 SQL Server SOS 基础架构上,该基础架构向 CLR 提供线程、内存分配和同步原语等服务,所以 SQLCLR 中的任何问题都会对 SQL 产生影响内部结构。特别是被 SQLCR“劫持”并在等待时阻塞的后台线程,它们将消耗 SQL OS 中宝贵的工作线程之一。执行外部访问(WCF、邮件、WebRequests、ftp 等)的 SQLCR 代码特别容易出现此问题。这个问题确实发生过,我已经看过好几次了。 SQL 最终冻结
  • @Matt 锁定问题是 CLR 触发器或所有触发器特有的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-20
  • 2017-11-06
  • 2017-10-07
  • 2010-11-18
  • 1970-01-01
  • 2011-02-06
相关资源
最近更新 更多