我们有一个在 IIS 中承载的 WCF 服务,在服务器上运行。该服务连接到在另一台服务器上运行的 SQL Server 实例。在我们的代码中,我们打开和关闭每个请求的连接。WCF 服务每分钟向数据库发出多个请求。
如果我在不停止 WCF 服务的情况下重新启动 SQL 服务,WCF 服务会开始将错误记录到我们的错误日志中,这是完全正常的。
问题是,有时(并非总是(在 SQL 服务重新启动后,WCF 服务继续在每个请求上报告此错误:
Cannot open database "mydatabase" requested by the login. The login failed."
错误的堆栈跟踪以以下结尾:
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
发生这种情况时,我能够使用 SQL Management Studio(从运行 WCF 服务的同一台计算机(连接到数据库。若要解决此问题,我必须回收 WCF 服务的应用程序池。
所以我的问题是:什么会导致这种情况,我该怎么做才能确保我的应用程序可以从 SQL 重启中恢复?
PS:在我的开发盒(也运行 IIS(上,当我做同样的测试时,我几次收到相同的错误(我想数据库开始加载时(,然后它又开始工作了。
有时,从池中获取的连接是新连接(并且连接尝试成功(,有时会重复使用连接并且连接尝试失败。 并非所有断开的连接实际上都会重用,因为池程序可能会也可能不会检测到这种情况并从池中删除此类连接。
从这里:
如果存在与已消失的服务器的连接,则即使连接池程序未检测到断开的连接并将其标记为无效,也可以从池中提取此连接。发生这种情况时,将生成异常。但是,您仍必须关闭连接才能将其释放回池中。
如果很少创建连接,因此不会影响性能,则最好关闭池。只需将Pooling
设置为连接字符串中的no
。