如果我从多个线程调用一些数据访问方法,我是否需要锁定数据库调用周围的代码以确保一致性,或者是否使用原子下的using语句?
public static DataRow GetData(Int32 id)
{
using (SqlConnection con = new SqlConnection(connectionString);)
{
con.Open();
SqlCommand cmd = ...
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(...)
cmd.Parameters.Add(...)
DataTable dt = new DataTable();
return new SqlDataAdapter(cmd).FillWithRetry(dt, sqlGetEmail.CommandText);
}
}
我认为一个线程不会影响定义的连接对象和另一个线程的“使用中”。
答案 0 :(得分:7)
使用语句 nothing 来处理线程安全(或缺少)。
它们仅确保在块结束时调用所使用对象的Dispose
方法;但在其他方面等同于手册try..finally Dispose
。
在这种特殊情况下:由于在每个线程上打开了 new 连接,因此它是“线程安全的”#。它仍然可能不是原子的。数据库或其他共享状态。
答案 1 :(得分:2)
我认为一个线程不会影响定义的连接对象和另一个线程的“使用中”。
所以我想你担心连接的并发访问。 using
语句不是锁。如果您想使用独占连接或任何其他实例,您应该使用:
lock(myConnection)
{
// your code
}
using
关键字对于here
但我认为此处存在其他误解:。在您的示例中,您的连接是一个局部变量,当控制流进入您的GetData方法时(即使在不同的线程中),实例化多次。因此,即使控制流重新进入该方法(并且在不同的线程中),也不会使用共享连接实例,每个进入该方法的人都会创建自己的实例。
如果连接实例是参数,将不同。然后你应该担心关于并发,并使用锁。
结论:在您的示例中,您不必担心连接实例并发访问,也不需要使用任何锁定语义。
有趣的是,使用using
的样本确实是正确的,因为Connection是IDisposable,所以你应该使用try / finally或更好的快捷方式应用一个确定性的处置保护:using
关键字。