SqlConnection / SqlCommand线程安全吗?

我目前正在创建一个WCF Web服务。

作为其工作的一部分,它不幸需要进行一些相当密集的计算,但是这些计算可能会在对Web服务的调用之间共享。 实际上 - 我们只需要进行一次计算,所有后来的调用都可以获得好处。

但是,由于WCF没有共享应用程序状态,因此将WCF设置为单实例模式似乎是合理的。 (每个客户都需要一些相关的计算,迫使我们重新计算每次可能会出现的问题,或者每个呼叫都是站不住脚的)

但是,我不太熟悉多线程的安全代码。 我一直在阅读它,因为我们的WCF代码都没有写入共享状态(除了易于保护的计算位),我几乎相信我不需要改变任何东西。

但是有一个障碍 - 我们使用SqlConnection和SqlCommand与我们的后端进行通信,我不确定是否可以指望这些线程安全?

编辑:我应该澄清,命令/连接总是本地的方法。 我们正在谈论一种模式:

using sqlConn = new SqlConnection(...) {
 try {
  sqlConn.Open()
} catch () {
  throw new FaultException();
}
var cmd = new SqlCommand("Some SQL", sqlConn);
var reader = cmd.ExecuteReader();
//Read the stuff 
reader.Close();
//Return something
}

结束编辑

我查找了MSDN上的SqlCommand类:http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx,它说:“任何公共静态(在Visual Basic中为Shared)成员类型是线程安全的,任何实例成员不保证是线程安全的。“

我是否认为这是正确的解释这意味着MS不保证SqlCommand在多线程场景中工作?

如果没有,是否有一个线程安全的替代方案?

是的,我可以锁定我的web服务中的所有数据库访问方法,但a)它很丑陋,b)如果没有必要,我宁愿我不必:)

提前欢呼!


我是否认为这是正确的解释这意味着MS不保证SqlCommand在多线程场景中工作?

只要正确使用,它在多线程场景中工作正常。

如果有几个线程试图使用SAME SqlCommand,你认为会发生什么? 它怎么可能工作?

但如果使用不同连接的不同线程向同一个数据库发出不同的命令,则不会有问题。

有关MSDN上的线程安全性的说明真的被打破,措辞严重,必须由不知道线程安全性的人编写。

他们试图用这个消息说的东西(它被添加到MSDN上记录的99.9%的类和函数中)是:“这种类型的任何静态方法都可以安全地由多个线程同时调用。如果多线程同时调用实例,则不保证安全,但在不同对象上访问同一个成员是非常好的。“


我不是100%确定你想要与SqlCommand同时做什么,但无论内部线程安全,你肯定都会遇到问题,纯粹是因为使用SqlCommand需要它保持状态,例如

SqlCommand cmd = myConnection.CreateCommand();
cmd.CommandText = "......";
cmd.Parameters.Add(.....);
cmd.ExecuteNonQuery();

如果您尝试通过多个线程共享相同的命令,则在使用它时必须锁定某些内容。

就SqlConnection而言,它只允许您一次打开一个查询,因此如果您使用的是DataReader,则需要再次锁定某些内容。 如果你想在同一时间运行多个事物,使用多个连接/命令是很重要的。

当你说WCF没有共享应用程序状态时,我也不确定你的意思 - 这不一定是真实的,它取决于你如何托管你的WCF应用程序。 如果它是在aspNetCompatibilityEnabled="true"设置的IIS下托管的WCF服务,那么您仍然可以在Web站点中获得Application对象。 如果您还没有使用aspNetCompatibility,还有其他选项。


只需使用来自一个线程的连接和命令,并且不关心那些应用程序级别的线程问题。 SQL服务器足以处理并发性,无需锁定代码。 .Net连接池也可以快速检索有效的连接。

我并不是说你所做的整个WCF层不应该关心线程,但是它的DAL必须依靠db锁而不是.net锁来工作。

链接地址: http://www.djcxy.com/p/20365.html

上一篇: Is SqlConnection / SqlCommand thread safe?

下一篇: How to implement the factory method pattern in C++ correctly