在同一时间运行同一过程的多个SQL/CLR调用(如线程)
本文关键字:调用 CLR 线程 SQL 运行 同一时间 过程 | 更新日期: 2023-09-27 18:03:23
我有一个单例(因为我认为有这些可用的所有时间是有用的)来表示一些设置,这将清除旧的,并在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 Server中使用不安全的权限。要注意这一点。您可以通过使用包装器类
来避免此需求。class MutableCell<T> { public volatile T value; }
static readonly MutableCell<...> myVar = new ...();
我添加了volatile
,这在这里是必需的,因为多个线程正在竞相读写该变量。
只需以事务方式重新加载并使用ConcurrentDictionary。
起点:http://msdn.microsoft.com/en-us/library/dd287191 (v = vs.110) . aspxhttp://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.aspxhttp://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx
SQL-CLR中的线程与普通的windows代码相当不同,因为它是由称为"SQLOS"的东西处理的。线程被分配给给定任务的调度器,它们不能重新分配给不同的线程,因此您可以在那里做一些假设。也就是说
不幸的是并发字典使用了锁,所以你必须非常小心,因为它需要"不安全"的权限集。
Adam Mechanic在这方面做了一个很好的演讲:http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/DBI-B404
当你运行一个进程时,它基本上是作为自己的线程分离出来的。所以两个调用它的人会发生冲突。