Мое приложение требует входа пользователя и позволяет редактировать список вещей. Однако кажется, что если один и тот же пользователь всегда входит в систему и выходит из него и редактирует этот список, этот пользователь будет запускаться в «System.Data.SqlClient.SqlException: Timeout истек». ошибка. Я прочитал комментарий об этом, возможно, вызванный незафиксированными транзакциями. И у меня есть одно приложение.Возможная утечка соединения, вызывающая ошибку «System.Data.SqlClient.SqlException: Timeout expired» в SQL Server?
Я предоставлю код, с которым я работаю, и там есть утверждение IF, в котором я был немного немного, но это казалось разумным делом.
Я просто расскажу, что здесь происходит, есть список объектов для обновления или добавления в базу данных. Новым объектам, созданным в приложении, присваивается идентификатор 0, а существующие объекты имеют собственные идентификаторы, созданные из БД. Если пользователь хочет удалить некоторые объекты, их идентификаторы хранятся в отдельном списке целых чисел. После того, как пользователь готов сохранить свои изменения, два списка передаются в этот метод. С помощью оператора IF добавляются объекты с идентификатором 0 (с использованием Add хранимой процедуры), и те объекты с ненулевыми идентификаторами обновляются (используя хранимую процедуру Update). После этого цикл FOR проходит через все целые числа в списке «удаление» и использует удаление хранимой процедуры для их удаления. Для этого используется транзакция.
Public Shared Sub UpdateSomethings(ByVal SomethingList As List(Of Something), ByVal RemovalList As List(Of Integer))
Using DBConnection As New SqlConnection(conn)
DBConnection.Open()
Dim MyTransaction As SqlTransaction
MyTransaction = DBConnection.BeginTransaction()
Try
Using MyCommand As New SqlCommand()
MyCommand.Transaction = MyTransaction
MyCommand.CommandType = CommandType.StoredProcedure
For Each SomethingItem As Something In SomethingList
MyCommand.Connection = DBConnection
If SomethingItem.ID > 0 Then
MyCommand.CommandText = "UpdateSomething"
Else
MyCommand.CommandText = "AddSomething"
End If
MyCommand.Parameters.Clear()
With MyCommand.Parameters
If MyCommand.CommandText = "UpdateSomething" Then
.Add("@id", SqlDbType.Int).Value = SomethingItem.ID
End If
.Add("@stuff", SqlDbType.Varchar).Value = SomethingItem.Stuff
End With
MyCommand.ExecuteNonQuery()
Next
MyCommand.CommandText = "DeleteSomething"
For Each ID As Integer In RemovalList
MyCommand.Parameters.Clear()
With MyCommand.Parameters
.Add("@id", SqlDbType.Int).Value = ID
End With
MyCommand.ExecuteNonQuery()
Next
End Using
MyTransaction.Commit()
Catch ex As Exception
MyTransaction.Rollback()
'Exception handling goes here '
End Try
End Using
End Sub
Есть три хранимые процедуры, используемые здесь, а также некоторые зацикливания, так что я могу видеть, как можно что-то держит все вверх, если список достаточно велик.
Я использую Visual Studio 2008 для отладки и использую SQL Server 2000 для БД.
Редактировать: Я все еще, кажется, получаю эту ошибку. Я даже удалил всю транзакционную вещь, и я все еще сталкиваюсь с ней. На этом этапе я предполагаю, что здесь происходит какая-то утечка. Я пробовал не использовать USING-заявления и явно сообщать команде и подключению себя, но не кубиками. Использование памяти с помощью SQL Server также очень сильно возрастает, если этот метод называется много за короткий промежуток времени.
Я читал, что увеличение свойства CommandTimeout SQLCommand поможет. Мне интересно, есть ли большие недостатки или последствия от этого.
BTW, я думаю, вы должны добавить «Rethrow» после откат в предложении catch. Вы на самом деле не исключали _handled_ исключение, поэтому вы должны разрешить его распространять. –
Я, должно быть, случайно удалил обработку исключений из образца, который я разместил, но спасибо, что указал на это. :) – Michael