В настоящее время у меня есть серьезная проблема с одним из моих веб-приложений, которое запускается в Timeout Exception около полудюжины раз в день.InvalidOperationException: Timeout - рекурсивный доступ к БД
Ошибка: «Период ожидания, прошедший до получения соединения из пула. Возможно, это произошло из-за того, что были использованы все объединенные соединения и максимальный размер пула».
После многих поисковых запросов я выяснил, что проблема имеет какое-то отношение к незамкнутым соединениям. Поэтому я проверил все функции, которые имеют доступ к базе данных в любом случае, пока я не наткнулся на это один:
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
Как вы можете видеть эту функцию выполняет хранимую процедуру и запускает результаты через время цикла, где он вызывает функцию снова если определенное условие - значениеInColl-. Таким образом, возможно, что существует 20 или более открытых соединений. Он не имеет ничего общего с значением тайм-аута, которое устанавливается через GetDataReaderFromStoredProcedure до 600, которое на самом деле должно быть достаточно. Разумеется, я удвоил стоимость и выкажу ее сегодня вечером. Я посмотрю, помогло ли это в следующий день. Я считаю, что проблема в том, что слишком много открытых подключений одновременно, из-за рекурсивной функции, но я не знаю, как это решить.
Я не мог найти ничего о том, как отредактировать максимальные соединения. Я даже не совсем уверен, где его установить. Это IIS, сама БД или это параметр программирования (VB.net/ASP.NET). Было бы хорошо, если бы вы, ребята, могли помочь мне здесь.
[EDIT] Хорошо, у кого-то возникла идея повторно использовать переменную соединения, но это не сработает, поскольку datareader все еще работает. Пока он не закрыт, я не могу повторно использовать соединение, и я не могу закрыть datareader, потому что я могу потерять данные, если я это сделаю. В то время как петля для dr.read не закончился, но .. С другой стороны, я удалил (в значительной степени бесполезна) внешний, а и б Условный пункт в обмен:
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
Ах, это отличная идея. Поэтому я в основном использую одно соединение вместо того, чтобы открываться один за другим и закрывать его потом. Я проверю это. Спасибо приятель. :) – OhSnap
Я так думаю, но это немного зависит от того, что делает StoredProc - если есть коммиты и откаты, там все может начаться очень беспорядочно. –
Uhm .. На самом деле я не уверен на 100%, почему я вставил другое, но мне это, вероятно, нужно ... Теперь, когда я смотрю на него, хотя кажется, что это бесполезно. Я посмотрю на это позже. Хранимая процедура - это просто простой оператор select. – OhSnap