【问题标题】:Threading in CLR in SQL Server 2008SQL Server 2008 中的 CLR 中的线程
【发布时间】:2011-09-29 09:58:07
【问题描述】:
我有一个在SQL Server2008 下运行的CLR 进程。它构建了几个表数据的缓存,以保存在静态类中,以供其他调用稍后使用。
我的问题是我是否可以通过生成线程来加载缓存中的每个数据集/表来改进加载此缓存的过程?
过去我已经避开了这一点,因为各种帖子都建议将线程管理留给SQL Server。但是我真的可以加快这个过程。
目前它是加载每个数据集的顺序过程。如果我可以同时运行这些,那将非常方便。这是我在CLR 封面之外多次完成的过程,以获得一些额外的性能提升。
非常感谢任何想法帮助提示。
【问题讨论】:
标签:
.net
multithreading
sql-server-2008
clr
【解决方案1】:
您可以使用线程,但它们必须正常运行。否则您将失去使用它们的好处。
来自the CLR Host Environment
SQL Server 和 CLR 如何协同工作
本节讨论 SQL Server 如何集成线程,
SQL 的调度、同步和内存管理模型
服务器和 CLR。特别是,本节考察了
根据可扩展性、可靠性和安全性目标进行集成。
SQL Server 在本质上充当 CLR 的操作系统
它托管在 SQL Server 中。 CLR 调用低级例程
由 SQL Server 实现,用于线程、调度、同步、
和内存管理。这些是与其余部分相同的原语
SQL Server 引擎使用。这种方法提供了几个
可扩展性、可靠性和安全性优势。
可扩展性:通用线程、调度和同步
CLR 调用 SQL Server API 来创建线程,两者都用于运行用户
代码并供其内部使用。为了在之间同步
多个线程,CLR 调用 SQL Server 同步对象。
这允许 SQL Server 调度程序在一个
线程正在等待同步对象。例如,当
CLR 发起垃圾回收,它的所有线程都在等待垃圾
收集完成。因为 CLR 线程和同步
他们正在等待的对象是 SQL Server 调度程序已知的,SQL
服务器可以调度正在运行其他数据库任务的线程,而不是
涉及CLR。这也使 SQL Server 能够检测死锁
涉及由 CLR 同步对象获取的锁并使用
消除死锁的传统技术。
托管代码在 SQL Server 中抢先运行。 SQL Server 调度程序
有能力检测和停止没有屈服的线程
大量的时间。将 CLR 线程挂接到 SQL 的能力
服务器线程意味着 SQL Server 调度程序可以识别
CLR 中的“失控”线程并管理它们的优先级。这样的逃跑
线程被挂起并放回队列中。线程是
反复标识为失控的线程不允许运行一个
给定的时间段,以便其他正在执行的工作人员可以运行。
【解决方案2】:
跨调用共享静态数据 - 对于 CLR 调用来说不是一个好计划:
SQL Server documentation
编程模型限制
托管代码的编程模型
在 SQL Server 中涉及编写函数、过程和类型
通常不需要使用跨多个持有的状态
调用或跨多个用户会话共享状态。
此外,如前所述,共享状态的存在可能导致
影响可扩展性和可靠性的关键异常
应用程序。
鉴于这些考虑,我们不鼓励使用静态变量
SQL Server 中使用的类的静态数据成员。为了安全和
EXTERNAL_ACCESS 程序集,SQL Server 检查
在 CREATE ASSEMBLY 时进行组装并且无法创建此类
如果发现使用静态数据成员和变量,则程序集。