Sql Server 2008 Закрытие соединения после удаления базы данных

StackOverflow https://stackoverflow.com/questions/821407

Вопрос

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

  

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

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

  

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

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

<Ол>
  • Откройте соединение с базой данных и выполните команду sql
  • Удалить базу данных
  • Повторно создайте базу данных
  • Откройте новое соединение с той же базой данных и попытайтесь выполнить команду для него
  • Результат: я получил исключение

    Вот код:

    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, что также сработало.

    Это было полезно?

    Решение

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

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

    Другие советы

    Не знаю о 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 ) Мне очень интересно узнать, работает ли это.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top