我正在考虑从 Sql Server 2005 中的 UDF 访问一些 CLR 代码。
我听说过 CLR 代码中抛出的未处理异常会导致服务器瘫痪的故事。
显然我的函数将包含一个 try-catch 块。但是,某些异常(stackoverflow)可以跳过捕获。
有没有人有一套指导方针可以完全消除(或最小化)我的 CLR 代码导致服务器崩溃的风险。
我正在考虑从 Sql Server 2005 中的 UDF 访问一些 CLR 代码。
我听说过 CLR 代码中抛出的未处理异常会导致服务器瘫痪的故事。
显然我的函数将包含一个 try-catch 块。但是,某些异常(stackoverflow)可以跳过捕获。
有没有人有一套指导方针可以完全消除(或最小化)我的 CLR 代码导致服务器崩溃的风险。
未处理的异常对 SQL Server 有不利影响,但不利的程度取决于引发的异常的严重性。
一般来说,您使用受约束的执行区域来指示一段代码在失败时可能会影响的范围(进程、应用程序域、线程等)。SQL Server 使用它来确定是否只是中止当前查询/请求,或者在出现更严重错误的情况下进一步处理。
MSDN 杂志上有一篇很好的文章谈到了 CER,以及 SQL Server 如何利用它们:
http://msdn.microsoft.com/en-us/magazine/cc163716.aspx#
此外,这里列出了专门针对为 SQL Server 开发 CLR 代码的最佳实践:
代码有什么作用?
我建议您考虑通过在不首先使用 CLR 的情况下实现目标来完全避免风险,而不是使用您知道很可能会增加耦合和复杂性并且完全不可移植的技术。但如果我不知道问题出在哪里,或者您是否真的需要 CLR,我不能推荐任何东西。
CLR 代码中未捕获的异常不会关闭服务器。CLR 代码在单独的应用程序域中运行,并且是隔离的。最可能发生的(这不太可能)是异常会关闭应用程序域,并导致应用程序域被卸载。这将使其a)在下一个请求时重新加载,或b)在问题得到解决或部署新版本的程序集之前被禁用。
所以至多那个特定的 CLR 程序集会被禁用,调用会话会收到错误消息。错误的 CLR 代码极不可能导致整个 sql server 实例崩溃;如果是这样,我会说这是微软的错误,而不是 CLR 函数或存储过程中的错误。
极有可能的情况是未捕获的 .net 异常将被转换为 tsql 错误消息。最多,tsql 连接会被终止;很可能会导致错误消息。
我强烈建议抑制使用 CLR 函数进行并行查询的能力。您的里程可能会有所不同,但我发现这消除了我的一些 SQL 引擎错误。
http://msdn.microsoft.com/en-us/library/ms181714.aspx
WITH( MAXDOP 1)