我们有一个基于 ADO.NET 构建的应用程序。我们遵循一些简单的最佳实践,使我们能够利用连接池。例如,使用数据库的代码块可能如下所示:
using( DbConnection dbConnection = GetDatabaseConnection() ) { doWork(); }
FWIW,GetDatabaseConnection 没有什么特别之处。它与运行 MSSQL Server 2000 的数据库建立连接。实际上,它的内容如下:
DbConnection GetDatabaseConnection() { return GetConnection(MyConnectionString); } DbConnection GetConnection(String connectionString) { try { SqlConnection dbConnection = new SqlConnection(connectionString); dbConnection.Open(); return dbConnection; } catch( InvalidOperationException ex ) { handleError(ex); throw; } catch( DbException ex ) { handleError(ex); } }
因此,我们的连接在块作用域的末尾被处理掉了。然而,当我们开始测试应用程序时,我们遇到了一个小故障。我们发现我们的应用程序非常突发,这意味着有时它会变得非常健谈,然后会沉默一段时间。结果是我们可以同时拥有多个线程来获取连接。
所以假设你有 10 个线程。一批工作(请不要试图改写这批工作)到达并被分割成几个线程。然后每个线程都尝试获得连接和繁荣,我遇到了 InvalidOperationException。我已经调整了 ConnectTimeout,所做的只是延长时间,直到我遇到一系列异常。一旦我通过了“结束”阶段,应用程序就很好了。然后它再次停顿,连接“消失”并且该过程再次开始。
我也尝试过调整 LoadBalanceTimeout 但异常继续出现。你们中有人见过这个问题吗?任何想法......我会扔掉我自己的几个。
- 持续保持一些连接“热”
- 尝试再次打开连接,最多尝试 # 次
- 实现我自己的连接池(哎呀,对重新发明轮子不感兴趣)
编辑:
我读过的大多数论坛都不鼓励增加连接池的大小。默认情况下,连接池的上限为 50 个连接(这绰绰有余——如果我必须增加它,其他地方就会出现根本问题)。我注意到的是,当 ConnectTimeout 较低时,会发生 InvalidOperationException。就好像连接的启动时间太长并且待处理的连接都超时了。
MARS 当然是一个选项... InvalidOperationException.Message 的文本是:
超时已过。在从池中获取连接之前超时时间已过。这可能是因为所有池连接都在使用中并且达到了最大池大小。