【问题标题】:SQL Server CLR static variables set back to nullSQL Server CLR 静态变量设置回 null
【发布时间】:2017-03-28 07:45:05
【问题描述】:

我有一个加载到 SQL Server 中的 CLR DLL(用 C# 编写的源代码)。初始化过程很昂贵,所以我通常只想做一次。但是,有时可能需要再次初始化,我不想重新启动 SQL Server 来执行此操作。因此,我没有将这些静态变量标记为只读。我的问题是我的静态变量以看似随机的方式重置为 null。我非常有信心我没有任何线程问题,而且我的代码都没有将这些值设置为 null 。通过分析我的日志文件,我只能猜测 SQL Server 以某种方式将值重置为 null(也许有时会重新加载 DLL?)。 SQL Server 会这样做吗?如果是这样,有没有办法将其配置为不?

【问题讨论】:

  • 描述几乎与 SQLCLR 函数或聚合应该是相反的。 SQLCLR 类使用 SQL Server 的线程在 SQL Server 的内存空间中运行。它的生命周期由 SQL Server 控制。因此它不应该执行昂贵的初始化,也不需要它。它不应该有静态变量。它不应该浪费可用于缓存数据的内存。换句话说,你确实有线程问题,但这些可能是你的问题中最少的
  • 代码在哪里,它试图做什么?为什么 SQLCLR 程序集需要任何类型的初始化?没有代码就无法提供帮助,除了注意 SQLCLR 类不应该以这种方式工作
  • 此代码正在与密钥管理器联系以导出加密密钥。我将密钥缓存在内存中,以便不必反复联系密钥管理器(因为这是一个昂贵的过程)。不幸的是,我不允许发布这个特定项目的任何代码。
  • 您描述的是外部应用程序或服务的工作,而不是 SQLCLR。只是不要这样做。使用单独的服务,或使用 SQL Server 的内置密钥管理功能。至于“缓存”,您实际上是在 窃取 缓冲内存来保存不应保存在 SQL Server 的 内存中的内容。
  • 您如何以及何时初始化该值?根据您的尝试,可能还有一两个其他选项可供尝试。查看 SQL Server 错误日志,您是否看到与该数据库和所有者的应用程序域相关的条目由于内存压力而被标记为卸载,然后被卸载?

标签: c# .net sql-server sqlclr


【解决方案1】:

SQL Server 会根据需要加载和卸载 CLR 模块(在内存压力下,如果出现未处理的异常,more on it here)。即使您能够弄清楚所有相关的条件和时间,这也可能在未来的版本中发生变化。

保留大量数据不会很好地扩展。为此编写一个 Windows 服务,并通过 tcp 从您的托管 UDF 调用它(例如)。如果您确实需要进程内状态,请使用持久缓存机制而不是静态变量(数据库、文件系统) - 或者预计静态变量可以随时变为空,每当发生时重新初始化它们,没有任何问题除了可扩展性问题和并发/同步之外,使用这种方法本身

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多