C# 同一过程的多个SQL/CLR调用是否同时运行(如线程)?
我有一个单例(因为我认为始终提供这些设置是有用的)来表示一些设置,这些设置将在clr过程调用开始时清除旧设置并从数据库加载新设置 但是如果CLR调用像线程一样处理,我可能会在某个时刻遇到问题,即设置在我想要访问它们的时候被清除 那么这会是一个问题吗?我可以用一个简单的对象锁来解决这个问题吗 编辑: 代码示例设置:C# 同一过程的多个SQL/CLR调用是否同时运行(如线程)?,c#,sql-server,clr,sqlclr,C#,Sql Server,Clr,Sqlclr,我有一个单例(因为我认为始终提供这些设置是有用的)来表示一些设置,这些设置将在clr过程调用开始时清除旧设置并从数据库加载新设置 但是如果CLR调用像线程一样处理,我可能会在某个时刻遇到问题,即设置在我想要访问它们的时候被清除 那么这会是一个问题吗?我可以用一个简单的对象锁来解决这个问题吗 编辑: 代码示例设置: public class Settings { public static Settings Default { get { return _defau
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"] }
}
}
只需以事务方式重新加载并使用ConcurrentDictionary即可 起点:
SQL-CLR中的线程与普通windows代码有很大不同,因为它由一种称为“SQLOS”的东西来处理。线程被分配给给定任务的调度程序,并且它们不能重新分配到其他线程,因此您可以在其中作出一些假设。也就是说 不幸的是,并发字典使用了锁定,因此您必须非常小心,因为它需要“不安全”的权限集 Adam Mechanical在这方面做了很好的介绍:
当你运行一个进程时,它几乎是作为自己的线程旋转出来的。因此,两个人打电话会发生冲突 最简单的方法是不改变现有的字典,而是创建一个新的字典,并以原子方式将其写入全局变量 为了拥有非只读静态变量,您需要SQL Server中的不安全权限。请注意这一点。您可以通过使用包装器类来避免此要求
class MutableCell<T> { public volatile T value; }
static readonly MutableCell<...> myVar = new ...();
类可变单元格{public volatile T value;}
静态只读可变单元格myVar=new…();
我添加了volatile
,这在这里是必需的,因为多个线程正在竞相读取和写入该变量
一般来说,在SQLServer内部执行线程和可变状态并不是最好的主意。最好避免。你有风险引入非常困难和灾难性的bug。不过,您的场景看起来是合法的。您能展示一下您的代码吗?如果您在问题中明确表示您是在专门讨论SQL/CLR,那将是一个好主意。这个问题目前只隐藏在标记中。我用一个代码示例和一个更好的标题更新了这个问题。仅仅使用线程安全的dict并不能使所有操作都是线程安全的。他仍然可以从不同的线程中看到一个空的dict。
class MutableCell<T> { public volatile T value; }
static readonly MutableCell<...> myVar = new ...();