gpt4 book ai didi

c# - SQL Server CLR 线程

转载 作者:太空狗 更新时间:2023-10-29 20:33:15 26 4
gpt4 key购买 nike

我一直在努力使用 SQL Server CLR 存储过程。

背景:

我们使用的是 SQL Server 2014,并且已经实现了一个调用客户 Web 服务的 CLR 存储过程。

线程最初用于不减慢 SQL Server CLR 的主线程。

虽然现在我知道在 CLR 下使用线程并不是最好的主意,但它已经正常工作了 6 年(自 SQL Server 2008 以来)。它最近已迁移到 SQL Server 2014。

问题

在我的开发机器上,与在测试系统上一样,我们的解决方案没有问题。

在客户系统上,调用 Web 服务的线程由于某种原因从未执行。

我可以从日志文件中看到,在线程执行之前一切正常。

没有特定的错误,什么都没有。

我们一直在尝试更改权限,但没有成功。因此,我认为这不是许可问题。

问题

  • 有谁知道如何改变行为?我们找不到任何可能起作用的配置。
  • 完全删除线程并直接在 SQL Server 主线程上调用 Web 服务是个好主意吗?

  • 谢谢你的任何建议,
    彼得

    最佳答案

    不确定问题 #1,尽管考虑到问题 #2 的建议,这可能无关紧要。尽管如此,SQL Server 2008(它运行的地方)和 SQL Server 2014(它不运行的地方)之间的一个区别是 SQL Server 链接到的 CLR 版本。 SQL Server 2005/2008/2008 R2 链接到 CLR v2.0,而 SQL Server 2012 和更新版本链接到 CLR v2.0。由于您没有看到错误,而您的客户端是,我会确保他们的系统已更新到您正在运行的相同 .NET Framework 版本。

    对于问题#2,我建议删除多线程。这有太多潜在的问题,并且需要大会是UNSAFE .如果删除线程,则可以将Assembly 设置为EXTERNAL_ACCESS .

    如果您想减少争用,那么假设 Web 服务调用是针对相同的 URI,那么您需要增加允许的并发 Web 请求数。这可以通过设置 ServicePointManager.DefaultConnectionLimit Property 来完成。 .默认值为 2。这意味着,任何其他请求都将等待,直到当前 2 中的一个关闭。

    另外,一定要正确DisposeWebRequest .

    关于进行可能无法快速完成的外部调用(即 Web 服务)的担忧是 SQL Server 使用协作多任务处理,其中每个线程负责在各个​​点“让出”控制权给调度程序(有效地暂停它),以便调度程序可以随机播放并运行当前“休眠”的其他内容。通常可以通过执行以下至少一项操作来减轻对 SQLCLR 代码的这种担忧:

  • 执行数据访问/查询实例
  • 调用 thread.sleep(0);

  • 但是,外部调用不是在进行数据访问,您无法轻松调用 thread.sleep(0)在等待 WebResponse 的同时去完成。是的,您可以在单独的线程上调用 WebService,并在等待它完成的同时,假设您只是在循环和检查 sleep(x)将允许产量。

    但是异步调用 Web 服务是必要的吗?它肯定有要求大会被标记为 WITH PERMISSION_SET = UNSAFE 的缺点。 .这在很大程度上取决于调用通常需要多长时间,以及被调用的频率。调用越频繁,任何延迟越有可能,至少部分是由每个 URI 允许的并发连接数的默认值较低引起的。这与我在顶部提出的建议有关。

    但是如果您想了解 SQL Server 的实际工作方式,这应该很容易测试。在我的笔记本电脑上,我转到对象资源管理器中的服务器“属性”,转到“处理器”,取消选中“自动设置处理器关联...”选项,在树 View 中的“处理器关联”下仅选择一个 CPU在对话框中间,单击“确定”,然后重新启动服务。然后我设置了一个网页,它只调用了 60 秒的“ sleep ”。我有一个调用网页的 SQLCLR TVF,所以我在两个不同的选项卡/ session 中同时运行它。在第三个选项卡/ session 中,我运行了:

    SELECT SUM(so1.[schema_id]), so1.[type_desc], so2.[type_desc]
    FROM sys.objects so1
    CROSS JOIN sys.objects so2
    CROSS JOIN sys.objects so3
    CROSS JOIN sys.objects so4
    CROSS JOIN sys.objects so5
    WHERE so3.[create_date] <> so4.[modify_date]
    GROUP BY so1.[type_desc], so2.[type_desc], so5.[name]
    ORDER BY so2.[type_desc], so5.[name] DESC;

    最后,在第 4 个选项卡中,在启动前 3 个选项卡后,我运行以下命令来监视系统:

    SELECT * FROM sys.dm_os_schedulers WHERE [scheduler_id] = 0;

    SELECT *
    FROM sys.dm_exec_requests
    WHERE [scheduler_id] = 0
    AND [status] <> N'background'
    ORDER BY [status] DESC, session_id;

    运行 SQLCLR 函数的 2 个 session 的状态始终为“正在运行”,而在选项卡 3 中运行该丑陋查询的 session 的状态始终为“可运行”。但可以肯定的是,当 SQLCLR 函数都没有执行时,再次运行那个丑陋的查询,与运行 SQLCLR 调用正在休眠的网页的 2 个 session 同时运行时所用的时间相同,时间为 1 分 14 秒60 秒。

    请不要推断运行 SQLCLR 代码进行 Web 调用是没有成本的。由于这些线程一直都很忙,如果系统很忙,那么 SQL Server 分配这些线程以更快地完成其他查询的能力就会降低。但似乎可以肯定地得出结论,至少在低到中等负载的系统上,通过添加线程获得的好处似乎不值得增加复杂性的成本(尤其是因为现在有一个尚未可重现的调试问题)。

    关于c# - SQL Server CLR 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35116558/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com