我应该在C#数据库调用周围放置锁定语句吗?

时间:2012-01-30 03:22:12

标签: c# locking

我正在创建一个类,用作在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之前立即生效吗?

非常感谢

5 个答案:

答案 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;

只需对您的应用程序进行额外的控制。