我正在创建一个类,用作在SQL Server数据库中读取,插入和更新值的门户。这个类实现了单例设计模式,因此任何时候都只有一个这个类的实例。
此类为数据库值(读取,写入和删除)的每个操作都有单独的方法,并且每个方法都将打开SQLConnection,create,populate&执行SQLCommand,最后在完成后关闭连接。
以下是添加值的示例:
public void AddGlossaryValue(string name, string value)
{
SqlConnection connection = null;
SqlCommand command = null;
try
{
connection = new SqlConnection(connectionString);
connection.Open();
command = new SqlCommand(SQL_INSERT_COMMAND, connection);
command.Parameters.Add("@name", SqlDbType.NVarChar, 50);
command.Parameters.Add("@value", SqlDbType.NVarChar, 50);
command.Parameters["@name"].Value = name;
command.Parameters["@value"].Value = value;
command.ExecuteNonQuery();
}
catch (Exception ex)
{
// handle exception - omitted in this example because it's irrelevant
}
finally
{
try
{
connection.Close();
}
catch (Exception) { }
}
}
我来自Java背景,通常您会将此类方法声明为Synchronized,这意味着该方法一次只能从一个源执行。从我对C#的研究看来,实现这一目标的典型方法似乎是锁定和反对。
然而,我的问题是,在上述情况下会推荐使用,如果是,那么锁定对象放在哪里?它会在创建SQLConnection之前立即生效吗?
非常感谢
答案 0 :(得分:3)
为什么要锁定?您没有在dll代码中使用任何共享资源。
抓住你可能从碰撞中看到的sql错误。如果你插入已经存在的东西,那么你可以做任何恰当的事情。
保存代码中共享资源的锁定;在需要确保行列式行为的地方,可以访问多个线程。这段代码看起来就像你只是向数据库发送一些东西,你不会得到任何你不能通过在这里使用锁来解释的行为。
答案 1 :(得分:1)
我并不喜欢将Singleton用于此目的。使用单个实例将为线程安全带来重大飞跃。无需锁定。
答案 2 :(得分:1)
这段代码不需要锁,因为您没有访问任何共享状态。但是你对“缓存键/值对列表”的评论肯定需要围绕读/写列表。
答案 3 :(得分:0)
虽然我可以想象一些非常有用的案例(例如你使用的是SQLite),但在大多数情况下,自己做锁定是个坏主意。
答案 4 :(得分:0)
您可以绝对使用lock(){//code block}
语句,它将确保线程执行不会进入临界状态。
但是,据我所知,如果您为每个命令使用不同的SqlConnections,那么它将自动变为线程安全。
此外,您可以使用SqlTransaction类。
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
command.Connection = connection;
command.Transaction = transaction;
只需对您的应用程序进行额外的控制。