По какой причине SQL сервер может не отвечать?

Всем привет. Есть небольшой кусочек кода обновления поля в таблице
private void SetResponsibleInSQL(long id, long resp)
		{
			using (SqlConnection con = new SqlConnection(@"Data Source=SERVER;Initial Catalog=DB;User ID=su;Password=123123;Timeout=300;"))
			{
				con.Open();
				using (SqlCommand comm = new SqlCommand()) {
					comm.Connection = con;
					comm.CommandTimeout = 300;
					comm.CommandText = String.Format("update Contractor set Responsible = {0} where Id = {1}", resp, id);
					comm.ExecuteNonQuery();
					comm.Dispose();
					comm.Cancel();
				}
				con.Close();
			}
		}


Выполняется данный метод в цикле. Каждая итерация, без вызова этой функции, занимает около 3х секунд. Это не единственный запрос к базе данных в итерации, но именно этот уходит в таймаут. Проходит то 8, то 10, то 3 итераций из 25 возможных. Я даже таймауты повысил на 300, но все равно не помогает.

Ошибка:
[System.Data.SqlClient.SqlException: Истекло время ожидания (Timeout). Время ожидания истекло до завершения операции или сервер не отвечает.
Выполнение данной инструкции было прервано.]

в System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
в System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
в System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout)
в System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
в System.Data.SqlClient.SqlCommand.ExecuteNonQuery()


Машина на которой выполняется код: i3-4130 3.4GHz, 8Gb RAM
Сервер SQL: i5-2500 3.6GHz, 12Gb RAM

UPD1: По рекомендациям Дмитрия Ковальского обновил метод
_con.Open();
SetResponsibleInSQL();
_con.Close();
//---------------------------
private void SetResponsibleInSQL()
{
	using (SqlCommand comm = new SqlCommand())
	{
		comm.Connection = _con;
		comm.CommandTimeout = 30;
		comm.CommandText = "BEGIN TRANSACTION;\n" + sqlQuery + "\nCOMMIT TRANSACTION;";
		Console.WriteLine(comm.CommandText);
		comm.ExecuteNonQuery();
	}
}


Теперь запрос выполняется 1 раз и в нем содержится N-ое кол-во update.
Пример CommandText:
BEGIN TRANSACTION;
update C SET C.Responsible = U.Id FROM [Contractor] as C, [User] as U where C.KodV1S = '000000014' and U.UserName = 'Янгуразова' and C.IsDeleted = 0;update C SET C.Responsible = U.Id FROM [Contractor] as C, [User] as U where C.KodV1S = '000000440' and U.UserName = 'Янгуразова' and C.IsDeleted = 0;update C SET C.Responsible = U.Id FROM [Contractor] as C, [User] as U where C.KodV1S = '000002351' and U.UserName = 'Бурмистрова' and C.IsDeleted = 0;update C SET C.Responsible = U.Id FROM [Contractor] as C, [User] as U where C.KodV1S = '000001702' and U.UserName = 'Пугач' and C.IsDeleted = 0;update C SET C.Responsible = U.Id FROM [Contractor] as C, [User] as U where C.KodV1S = '000002077' and U.UserName = 'Скоробогатова' and C.IsDeleted = 0;update C SET C.Responsible = U.Id FROM [Contractor] as C, [User] as U where C.KodV1S = '000001913' and U.UserName = 'Хромихина' and C.IsDeleted = 0;
COMMIT TRANSACTION;

Специально для Дмитрия резюмирую: даже такие действия не помогают решить проблему с TimeOut.
  • Вопрос задан
  • 2946 просмотров
Пригласить эксперта
Ответы на вопрос 1
@dmitryKovalskiy
программист средней руки
За циклическое выполнение такого кода наказывают рабочим местом в подвале без окошка. Уважаемый - старайтесь делать 1 скрипт, а не сотни. Выиграете тьму времени и сервак вздохнет с облегчением. Да, скрипт будет труднее и хитрее, но оптимизирование взаимодействия с базой - вообще дело не легкое, а вы тут одним клиентом создаете сотню соединений/разъединений хрен знает ради чего.

UPD: Вчитался немножко в код и не понял некоторых ваших телодвижений.
1) зачем делать using (SqlConnection con = new SqlConnection(),а затем con.Open(); и con.Close() на выходе? ну предположим что соединение не открыто при создании объекта, но при выходе из using и АВТОМАТИЧЕСКОМ вызове con.Dispose() соединение закроется.
2)
using (SqlCommand comm = new SqlCommand()) {
comm.Dispose();
comm.Cancel();
}
Во первых Dispose вызывается при выходе за границы using, а зачем вы вызываете Cancel вообще не представляю.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы