【问题标题】:Synchronize access to static variables in sql server SQLCLR同步访问sql server SQLCLR中的静态变量
【发布时间】:2009-08-16 16:04:48
【问题描述】:

我编写了一个集成在 sql server 中的程序集,提供了一些用 C# 编写的存储过程。该程序集有一个只读静态变量,其中包含一些配置数据。该数据通过存储过程进行操作,这些存储过程也由程序集提供。显然我必须同步访问这个静态变量。我尝试使用

lock(someGuard)
{
    // ... access static configuration
}

在我的配置类中。但后来我得到一个 HostProtectionException,告诉我,程序集必须以完全信任的方式运行才能做到这一点。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: c# sql-server synchronization sqlclr


    【解决方案1】:

    实际上有一个未记录的hack:用CompilerGenerated 属性装饰类。与任何未记录的解决方法一样,里程可能会因未来版本而异。

    但你不应该需要这个,如果静态是只读的,那么你可以将它声明为只读并且程序集将正常部署,只读静态在 SAFE 程序集中被接受。并且是真正的只读,锁守卫也是不必要的。

    如果您无法将其标记为只读并删除锁定,则表示不是只读的,您将处于移动的沙子领域。您可以阻止 SQL 工作人员并产生不可预测的结果(因此是 UNSAFE 要求)。 CompilerGenerated 技巧真的应该在大量的情况下使用,除非你完全理解其中的含义。您需要lock 这一事实有力地表明您的代码实际上对 SQL 和静态不安全。

    【讨论】:

    • 虽然技术上似乎确实有文档记录。 :-) 不过可能不支持这种用途。
    • 是的,它确实说This attribute allows SQL server to reference compiler-generated static values。 AFAIK 这是此属性的唯一用途。
    • 感谢您的提示!我的变量是只读的,但它的内部状态发生了变化。它包含一些我只想阅读一次的配置选项。是否有可能在 appdomain 启动时执行代码?在那种情况下,我的配置真的是只读的,我的问题就会消失。
    • @Achim:你不能在只读对象初始化时读取配置吗?例如:static readonly MyClass myField = MyClass.ReadConfig().
    • @Remus:我会试试的。那时我可以访问数据库吗?会检查的。 Sql server 2005 和 2008 在静态变量检查方面似乎有些不同。
    【解决方案2】:

    绕过此限制的唯一方法是将程序集部署为 UNSAFE。尽管如此,静态共享数据仍不符合建议:

    托管代码的编程模型 在 SQL Server 中需要函数, 程序和类型不 要求使用跨越的状态 多次调用或共享 跨多个用户会话的状态。 此外,如前所述, 共享状态的存在可能导致 影响的关键异常 可扩展性和可靠性 应用。

    鉴于这些考虑,SQL Server 不允许使用静态变量 和静态数据成员。为了安全和 外部访问程序集,SQL Server 检查程序集的元数据 在 CREATE ASSEMBLY 时,并且失败 创建这样的程序集,如果它 发现静态数据成员的使用 和变量。

    【讨论】:

      猜你喜欢
      • 2016-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-22
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多