【问题标题】:Do multiple SQL/CLR calls of the same procedure run at the same time (like threads)?同一过程的多个 SQL/CLR 调用是否同时运行(如线程)?
【发布时间】:2014-05-15 08:01:25
【问题描述】:

我有一个单例(因为我认为让这些始终可用会很有用)来表示一些设置,这将在 clr 过程调用开始时从数据库中清除旧设置并加载新设置。

但如果 CLR 调用像线程一样处理,我可能会在某个时候遇到问题,即设置在我想要访问它们的那一刻被清除。

那么这会是一个问题吗?我可以使用简单的对象锁来解决这个问题吗?

编辑:

代码示例设置:

public class Settings
{
    public static Settings Default
    {
        get { return _default ?? (_default = new Settings()); }
    }
    private static Settings _default;

    private Dictionary<string, string> _settingsDict;

    private Settings()
    {
        _settingsDict = new Dictionary<string, string>();
    }

    public void ReloadSettings()
    {
        _settingsDict.Clear();

        using (var connection = new SqlConnection("context connetion=true"))
        using (var command = connection.CreateCommand())
        {
            command.CommandText = ...
            connection.Open();

            // Read Settings with DataReader into _settingsDict
        }
    }

    public string Get(string key) {
        get { return _settingsDict["key"] }
    }
}

程序:

[SqlProcedure]
public static void InsertData(SqlString csv)
{
    Settings.Default.ReloadSettings();

    var setting = Settings.Default.Get("SETTING");

    using (var connection = new SqlConnection("context connetion=true"))
    using (var command = connection.CreateCommand())
    {
        ...
    }
}

【问题讨论】:

  • 你能展示你的代码吗?
  • 如果在您专门谈论 SQL/CLR 的问题中明确表示是个好主意。这目前仅隐藏在标签中。
  • 我已经用代码示例和更好的标题更新了问题

标签: c# sql-server clr sqlclr


【解决方案1】:

最简单的方法是不改变现有字典,而是创建一个新字典并将其自动写入全局变量。

为了拥有非只读静态变量,您需要 SQL Server 中的不安全权限。请注意这一点。您可以通过使用包装类来避免此要求

class MutableCell<T> { public volatile T value; }
static readonly MutableCell<...> myVar = new ...();

我在这里添加了volatile,这是必需的,因为多个线程正在竞相读取和写入该变量。

一般来说,在 SQL Server 内部进行线程化和可变状态并不是最好的主意。最好避免。您可能会引入非常困难和灾难性的错误。不过,您的方案看起来很合理。

【讨论】:

    【解决方案2】:

    【讨论】:

    • 仅仅使用线程安全的字典并不能使所有的操作都是线程安全的。他仍然可以看到来自不同线程的空字典。
    【解决方案3】:

    SQL-CLR 中的线程与普通的 Windows 代码完全不同,因为它是由称为“SQLOS”的东西处理的。线程被分配给给定任务的调度程序,它们不能重新分配给不同的线程,因此您可以在那里做出一些假设。那就是说

    不幸的是并发字典使用了锁定,因此您必须非常小心,因为它需要“不安全”权限集。

    Adam Mechanic 对这些东西做了很好的介绍: http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/DBI-B404

    当你运行一个 proc 时,它几乎是作为它自己的线程分拆出来的。所以两个人叫它会发生冲突。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      • 2021-06-29
      • 1970-01-01
      • 2011-05-20
      相关资源
      最近更新 更多