Sql Server 2008 Закрытие соединения после удаления базы данных - PullRequest
3 голосов
/ 04 мая 2009

У меня проблемы с удалением соединения SQL Server после того, как я сбросил и заново создал данную базу данных, и в следующий раз, когда я пытаюсь выполнить команду для нового соединения в той же базе данных, я получаю:

Произошла ошибка транспортного уровня при отправке запроса на сервер. (поставщик: поставщик общей памяти, ошибка: 0 - на другом конце канала нет процесса).

Вот версия TCP (если я пытаюсь подключиться к другому серверу)

Произошла ошибка транспортного уровня при отправке запроса на сервер. (провайдер: провайдер TCP, ошибка: 0 - существующее соединение было принудительно закрыто удаленным хостом.)

Вот шаги, чтобы воспроизвести проблему:

  1. Открыть соединение с базой данных и выполнить команду sql
  2. Удалить базу данных
  3. Пересоздать базу данных
  4. Открыть новое соединение с той же базой данных и попытаться выполнить команду для него

Результат: получаю исключение

Вот код:

using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=DBNAME;Integrated Security=True"))
{
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "UPDATE ...";
    cmd.ExecuteNonQuery();
}

string sql = "Alter Database DBNAME set single_user with rollback immediate drop database DBNAME";
var server = new Microsoft.SqlServer.Management.Smo.Server(".");
server.ConnectionContext.ExecuteNonQuery(sql);
server.ConnectionContext.Disconnect();

sql = File.ReadAllText("PathToDotSqlFile..."));
server = new Microsoft.SqlServer.Management.Smo.Server(".");
server.ConnectionContext.ExecuteNonQuery(sql);
server.ConnectionContext.Disconnect();

using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=WER_CONFIG;Integrated Security=True"))
{
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "UPDATE ...";
    cmd.ExecuteNonQuery();
}

Ошибка возникает в строке cmd.ExecuteNonQuery () в самом конце. Кажется, что даже если я создаю новое соединение каждый раз, когда я подключаюсь, сервер sql отслеживает что-то (или, возможно, код ADO.net), где в следующий раз, когда я запрашиваю соединение, он дает мне то, что уже используется или был закрыт на стороне сервера. Он не осознает, что он был закрыт сервером (возможно, из-за того, что база данных подключена к удалению), пока вы не попытаетесь выполнить для него другую команду.

Обратите внимание, что если я не выполню первый шаг выполнения начального запроса, и я просто отброшу базу данных, заново создаю ее и выполню команду, я не получу эту ошибку. Я думаю, что установление этого начального соединения перед удалением базы данных является важной частью этой ошибки.

Я также пытался использовать внешний процесс для удаления и воссоздания базы данных следующим образом:

ProcessStartInfo info = new ProcessStartInfo("sqlcmd.exe", " -e -E -S . -Q \"Alter Database DBNAME set single_user with rollback immediate drop database DBNAME\"");
var p = Process.Start(info);
p.WaitForExit();

info = new ProcessStartInfo("sqlcmd.exe", " -i " + PathToDotSqlFile);
p = Process.Start(info);
p.WaitForExit();

И это не помогло.

Есть ли способ создать новый SqlConnection и убедиться, что он чистый, а не из пула? Любые другие предложения о том, как решить эту проблему?

ОБНОВЛЕНИЕ: Использование SqlConnection.ClearPool () решило проблему, но я решил просто отредактировать строку подключения с помощью pooling = false, что также сработало.

Ответы [ 2 ]

7 голосов
/ 04 мая 2009

ADO.NET автоматически управляет пулом соединений. Когда вы «закрываете» соединение в вашем приложении, оно возвращается в пул и остается активным, если вы запрашиваете соединение с той же строкой соединения. Это может быть причиной того, что ваше «новое» соединение устарело.

Вы можете попытаться отключить это поведение, добавив pooling=false в качестве параметра в строку подключения.

3 голосов
/ 04 мая 2009

Не знаю о SQL2008, но это звучит как проблема с пулом соединений на стороне приложения. В прежние времена мы добавляли OLEDB Services = -1 в строку подключения, чтобы отключить пул соединений. Возможно, сейчас есть более элегантный способ сделать это.

edit: ADO.Net 2.0, кажется, добавил функцию ClearPool к объекту SQLConnection. (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool(VS.80).aspx) Мне очень интересно узнать, работает ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...