Пожалуйста, прочитайте весь вопрос, прежде чем отвечать. И я извиняюсь, я никогда не пишу короткие вопросы...
Я поддерживаю внутреннее веб-приложение C#, которое работает с SQL Server 2008 R2 в Windows Small Business Server 2011 SP1.
В последнее время мы получаем много тайм-аутов SQL, вот пример исключения:
System.Web.HttpUnhandledException: возникло исключение типа «System.Web.HttpUnhandledException». ---> System.InvalidOperationException: время ожидания истекло. Время ожидания истекло до получения соединения из пула. Это могло произойти из-за того, что все соединения в пуле использовались и был достигнут максимальный размер пула. в System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) в System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection externalConnection, DbConnectionFactory connectionFactory) в System.Data.SqlClient.SqlConnection.Open()
Я проверил несколько вещей, одна из которых — то, как код обрабатывает соединения и закрывает соединения. Я читал в других потоках, что использование оператора Using с вашим соединением является адекватным, поскольку оно «... оборачивает соединение, созданное в попытке ... наконец, и помещает вызов удаления соединения внутри, наконец». Соединение закрывается даже в случае исключения.
Итак, я согласен и использую этот метод в течение многих лет. Другие рекомендуют явно закрывать соединения даже при использовании инструкции Using с вашим соединением. Думаю, это было бы лишним...
Однако мой вопрос касается объекта команды. Кто-то еще написал большую библиотеку методов базы данных для этого приложения, и они (во всех методах базы данных) объявили объект SqlCommand ПЕРЕД оператором использования объекта SqlConnection. Они также присвоили объект соединения объекту команды перед оператором соединения using.
Лучше ли объявлять и использовать объект команды внутри оператора соединения, используя оператор, и может ли это делать другим способом, чтобы вызвать тайм-ауты соединения sql (за исключением других причин тайм-аутов соединения sql)? Возьмите этот код, например:
public Musician GetMusician(int recordId)
{
Musician objMusician = null;
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "selectMusician";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@id", recordId);
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
objMusician = new Musician((int)reader["id"]);
objMusician.Name = (string)reader["name"];
}
}
if objMusician != null)
{
objMusician.Albums = Albums.GetAlbums((int)objMusician.ID);
objMusician.Tours = Tours.GetTours((int)objMusician.ID);
objMusician.Interviews = Interviews.GetInterviews((int)objMusician.ID);
}
return objMusician;
}
Также знайте, что на вызывающих страницах есть перехваты попыток, и это страница, которая регистрирует ошибку в нашей базе данных журналов. Мы позволяем исключению подниматься до вызывающего метода на странице, и там оно обрабатывается.