简体   繁体   English

无状态WCF服务和数据库连接池

[英]Stateless WCF service and database connection pooling

The question has been asked before here in StackOverflow, but in my experience, the answers were actually wrong. 之前在StackOverflow中已经问过这个问题,但以我的经验,答案实际上是错误的。 At least for .NET Framework 4.0 and SQL Server 2005 they are wrong. 至少对于.NET Framework 4.0和SQL Server 2005,它们是错误的。

I would need help to sort this out once and for all. 我需要帮助来一劳永逸地解决这个问题。

The question is - can a stateless WCF service use database connection pooling in some way? 问题是-无状态WCF服务可以某种方式使用数据库连接池吗?

See Can a Stateless WCF service ... 请参阅可以无状态WCF服务...

The earlier answers essentially stated that there is no problem and no difference to any other ADO.NET scenarios. 较早的答案基本上表明,与任何其他ADO.NET方案一样,没有问题,也没有区别。 However, I have not been able to get a stateless WCF service to use the connection pooling EVER, while I can see it always work outside WCF services. 但是,我无法获得无状态的WCF服务来使用连接池EVER,尽管我看到它始终在WCF服务之外运行。 No matter what connection strings or parameters I am trying to use, it does not do it. 无论我尝试使用什么连接字符串或参数,它都不会这样做。

Database connection pooling is meant to be enabled by default, so a simple connection string should get me there, for instance on SQL Server Express: 数据库连接池是默认情况下启用的,因此一个简单的连接字符串应该可以使我到达那里,例如在SQL Server Express上:

SqlConnection sqlCn = new SqlConnection("Data Source=SERVER\SQLEXPRESS; Initial Catalog = xDB; Integrated Security = SSPI;")

Using this connection, in a Windows Form application, if I do 3 consecutive rounds of sqlCn.Open() -- query the database -- sqlCn.Close() , I am getting a long delay (for instance 2 seconds) on the first sqlCn.Open() , and no delays at all on queries and open / close afterwards. 使用此连接,在Windows窗体应用程序中,如果我连续进行了3轮sqlCn.Open() -查询数据库sqlCn.Close() ,则我在第一个获取的延迟很长(例如2秒) sqlCn.Open() ,查询完全没有延迟,然后打开/关闭。 Exactly what I expect with database connection pooling. 正是我期望的数据库连接池。

But if I make 3 calls to a WCF service containing the same sqlCn.Open() -- query the database -- sqlCn.Close() code, I am getting the 2 second initial slow startup for EVERY single call. 但是,如果我对包含相同sqlCn.Open()的WCF服务进行了3次调用-查询数据库sqlCn.Close()代码,则sqlCn.Close()单次调用都会有2秒的初始缓慢启动。

My guess is that the connection pooling is entirely controlled by the ADO.NET objects created by my code, and since I am instantiating any ADO.NET classes I use (such as SqlConnection etc) inside my WCF service, they get destroyed when my service call is over and the connection pool along with it. 我的猜测是,连接池完全由我的代码创建的ADO.NET对象控制,并且由于我在WCF服务中实例化了我使用的任何ADO.NET类(例如SqlConnection等),因此在我的服务中它们会被销毁通话结束,连接池也随之结束。

This may not be true, but if not, is there anything wrong with what I have done? 这可能不是正确的,但是如果不是,我所做的事情有什么错误吗?

Anyone have any experience with that? 有人对此有经验吗?

(Please do test any assumption or theory before posting) (请在发布前测试任何假设或理论)

1) Here's the documentation: 1)这是文档:

http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx http://msdn.microsoft.com/zh-CN/library/8xx3tyca.aspx

When a connection is first opened, a connection pool is created based on an exact matching algorithm that associates the pool with the connection string in the connection. 首次打开连接时,将基于精确匹配算法创建连接池,该算法将连接池与连接中的连接字符串相关联。 Each connection pool is associated with a distinct connection string. 每个连接池都与一个不同的连接字符串关联。 When a new connection is opened, if the connection string is not an exact match to an existing pool, a new pool is created. 当打开新连接时,如果连接字符串与现有池不完全匹配,则会创建一个新池。 Connections are pooled per process, per application domain, per connection string and when integrated security is used, per Windows identity. 每个进程,每个应用程序域,每个连接字符串以及使用集成安全性时,每个Windows标识都对连接进行池化。 Connection strings must also be an exact match; 连接字符串也必须完全匹配; keywords supplied in a different order for the same connection will be pooled separately. 对于同一连接,以不同顺序提供的关键字将被单独合并。

2) Per the same link, "By default, connection pooling is enabled in ADO.NET." 2)对于同一链接,“默认情况下,ADO.NET中启用了连接池”。

3) This is completely independent of whether the WCF call in question is stateless or not. 3)这完全独立于所讨论的WCF调用是否为无状态。

4) Finally: 4)最后:

We strongly recommend that you always close the connection when you are finished using it so that the connection will be returned to the pool. 强烈建议您在使用完连接后始终关闭该连接,以便将连接返回到池中。 You can do this using either the Close or Dispose methods of the Connection object, or by opening all connections inside a using statement in C#, or a Using statement in Visual Basic. 您可以使用Connection对象的Close或Dispose方法,或通过在C#中的using语句或Visual Basic中的using语句中打开所有连接来执行此操作。 Connections that are not explicitly closed might not be added or returned to the pool. 未显式关闭的连接可能不会添加或返回到池中。

I managed to resolve it myself. 我设法自己解决了。

I had to explicitly state "Pooling = true" (and add a non-zero "Min Pool Size") to my connection string. 我必须在连接字符串中明确声明“ Pooling = true”(并添加非零的“ Min Pool Size”)。 Then it was working consistently. 然后它一直在工作。 If this was not set, it would sometimes factually work as expected, but mostly not. 如果未设置,则有时实际上会按预期运行,但大多数情况下不会。

I tested it also with different user accounts (SQL Server authentication with user name / password versus "Integrated Security = SSPI"). 我还使用不同的用户帐户进行了测试(使用用户名/密码的SQL Server身份验证与“集成安全性= SSPI”)。 Both approaches work for a WCF service as long as you set "Pooling = true". 只要您设置“ Pooling = true”,这两种方法都适用于WCF服务。

No data if this is a problem only for my installation / SQL Server version / ADO.NET version but it sure did take quite a while to resolve. 如果这仅是我的安装/ SQL Server版本/ADO.NET版本的问题,则没有数据,但是确实需要花很长时间才能解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM