SqlConnection / SqlCommand线程安全吗?

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

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

但是,由于WCF没有共享应用程序状态,因此在单实例模式下设置WCF似乎是合乎逻辑的。 (每个客户端都需要进行一些计算,迫使我们重新计算它们,这可能是正常的,或者每次调用都是站不住脚的,这是不可能的)

但是,我不太熟悉保护multithreading的代码。 我一直在阅读它,因为我们的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中共享)成员类型是线程安全的。任何实例成员都不保证是线程安全的。“

我是否正确地解释了这一点,这意味着MS 不能保证SqlCommand在multithreading场景中工作?

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

是的,我可以在我的webservice中锁定所有数据库访问方法,但是a)它很丑陋b)如果没有必要我更喜欢我没有必要:)

提前干杯!

我是否正确地解释了这一点,这意味着MS不能保证SqlCommand在multithreading场景中工作?

只要您正确使用它,它在multithreading方案中工作正常。

如果多个线程尝试使用SAME SqlCommand,您认为会发生什么? 怎么可能有用呢?

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

关于MSDN上线程安全的注意事项真的很破碎,措辞也很差,必须由不知道线程安全的人编写。

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

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

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

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

就SqlConnection而言,它只允许你一次打开一个查询,所以如果你使用DataReaders,你又必须锁定一些东西。 如果要同时运行多个事物,则必须使用多个连接/命令。

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

只需使用knly一个线程的连接和命令,而不关心那些应用级别的线程问题。 sql server足以为您处理并发性而无需锁定代码。 .Net连接池也可用于快速检索有效连接。

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