目前,我的一个 Web 应用程序遇到了一个严重的问题,它每天运行大约六次超时异常。
错误:“在从池中获取连接之前已经过了超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小”。
经过大量谷歌搜索后,我发现问题与未关闭的连接有关。所以我检查了所有以任何方式访问数据库的函数,直到我偶然发现了这个:
Private Sub getOrgas(ByVal orgID As String)
Dim Id = orgID
orgColl.Add(Id)
While (Not IsNothing(Id))
Dim conn = Database.DbWrapper.GetConnection(1, Integration.Mandanten.DatabaseType.AddonSQL)
Dim paras As New HashSet(Of System.Data.Common.DbParameter)
Dim orgatmp As String
paras.Add(New SqlClient.SqlParameter("@Id", orgID))
Dim dr = Database.DbWrapper.GetDataReaderFromStoredProcedure("stp_Orgas_Get", paras, conn)
While dr.Read
If Not valueInColl(CStr(dr(0))) Then
orgatmp = dr(0).ToString
orgColl.Add(orgatmp)
getOrgas(orgatmp)
End If
End While
dr.Close()
conn.Close()
Id = Nothing
End While
End Sub
如您所见,该函数执行一个存储过程并通过一个while循环运行结果,如果特定条件-valueInColl-,它将再次调用该函数。现在以这种方式,可能有 20 个或更多打开的连接。它与通过 GetDataReaderFromStoredProcedure 设置为 600 的超时值无关,这实际上应该足够了。可以肯定的是,我将价值翻了一番,并将在今晚推出。我会在第二天看看这是否有帮助。我相信问题是由于递归功能,同时打开的连接太多,但我不知道如何解决这个问题。
我找不到有关如何编辑最大连接数的任何信息。我什至不完全确定必须在哪里设置它。是 IIS、数据库本身还是编程参数 (VB.net/ASP.NET)。如果你们能在这里帮助我,那就太好了。
[编辑] 好的,有人想重用连接变量,但这不会工作,因为数据读取器仍在运行。只要它没有关闭,我就不能以任何方式重用连接,也不能关闭数据读取器,因为这样做可能会丢失数据。dr.read 的 while 循环还没有结束,但.. 另一方面,我删除了(几乎没用的)外部 while 并使用了一个 If 子句作为交换:
Private Sub getOrgas(ByVal orgID As String, ByVal con As DbConnection)
Dim Id = orgID
Dim conn As DbConnection
Dim tmpOrga As String
orgColl.Add(Id)
If Not IsNothing(Id) Then
If IsNothing(con) Then
conn = Database.DbWrapper.GetConnection(1, Integration.Mandanten.DatabaseType.AddonSQL)
Else
conn = con
End If
Dim paras As New HashSet(Of System.Data.Common.DbParameter)
paras.Add(New SqlClient.SqlParameter("@Id", orgID))
Dim dr = Database.DbWrapper.GetDataReaderFromStoredProcedure("stp_Orgas_Get", paras, conn)
While dr.Read
If Not valueInColl(CStr(dr(0))) Then
tmpOrga = dr(0).ToString
orgColl.Add(tmpOrga)
getOrgas(tmpOrga, conn)
End If
End While
dr.close()
conn.Close()
Id = Nothing
End If
End Sub