Как автоматически закрывать соединения SQL Server из IIS для перестройки БД в Integration Test - PullRequest
1 голос
/ 06 октября 2011

Я играю с некоторыми подключениями к БД через WinForms и WebService, и я обнаружил, что при использовании веб-службы подключения не закрываются. Это вызывает затруднения в моем автоматическом тесте, потому что я уничтожаю и воссоздаю базу данных между тестами, поэтому у меня всегда одинаковое начальное состояние для каждого теста.

Фактический код доступа к данным для вызова одинаков в обоих случаях, например:

            using (DataHandler handler = new DataHandler(Config.ConnectionString()))
        {
            return handler.GetDbVersion();
        }

DataHandler использует контекст данных (созданный с помощью SqlMetal), чтобы загрузить целое число из таблицы БД и вернуть его.

Метод Dispose of DataHandler закрывает соединение и контекст данных:

    public void Dispose()
    {
        _data.Connection.Close();
        _data.Connection.Dispose();
        _data.Dispose();
    }

При запуске непосредственно из модульного теста - он проходит, после чего в БД не остается никаких соединений.

select spid, status, loginame, hostname, blocked, db_name(dbid), cmd from master..sysprocesses where db_name(dbid) = 'TEST_DATABASE'

Затем я обертываю это в [WebMethod] и помещаю в экземпляр IIS7:

    [WebMethod]
    public int GetDatabaseVersionNumber()
    {
        using (DataHandler handler = new DataHandler(Config.ConnectionString()))
        {
            return handler.GetDbVersion();
        }
    }

И тест вызывает веб-службу:

        int dbVersion = _webService.GetDatabaseVersionNumber();

Веб-служба создает контекст данных - получает номер - вызывает Dispose и затем возвращает номер. Однако соединение все еще «спит» в БД. Это означает, что когда я пытаюсь уничтожить и воссоздать базу данных для следующего теста, сбрасывается база данных (активное соединение).

select spid, status, loginame, hostname, blocked, db_name(dbid), cmd from master..sysprocesses where db_name(dbid) = 'TEST_DATABASE'

54  sleeping IIS APPPOOL\ASP.NET v4.0   PETE    0   TEST_DATABASE   AWAITING COMMAND

Я предполагаю, что это какой-то пул соединений, который обрабатывают IIS и SQL Server, чтобы уменьшить накладные расходы на все открытие и закрытие соединений от веб-запросов (полагаю, я не хотел бы связываться с этим в контексте развертывания веб-службы)

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

Какой лучший способ справиться с этим? (Это то, что мне нужно установить в IIS или в тестовой базе данных? Могу ли я определить это в строке подключения, чтобы это происходило только на тесте?)

Для информации

Решено добавлением следующего кода к методу тестирования:

            if (data.DatabaseExists())
        {
            data.ExecuteCommand("ALTER DATABASE TEST_DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATE;");
            data.ExecuteCommand("ALTER DATABASE TEST_DATABASE SET MULTI_USER;");
            data.DeleteDatabase();              
        }   

Обновление

Я обнаружил, что могу обойти эту проблему, добавив «Pooling = false» в строку подключения в модуле Test Unit App.Config. Кажется, это работает намного лучше, чем принудительное закрытие соединений, потому что, когда вы принудительно закрываете их, иногда БД недоступна для следующего теста в наборе (вы получаете ошибку типа «нет обслуживания на другом конце канала», потому что SQL ушел, но .net думает, что он все еще там).

Ответы [ 2 ]

2 голосов
/ 06 октября 2011

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

0 голосов
/ 06 октября 2011

Проверка с использованием Пул соединений с SQL Server , в котором указано

В ADO.NET 2.0 представлены два новых метода очистки пула: ClearAllPools и ClearPool .ClearAllPools очищает пулы соединений для данного провайдера, а ClearPool очищает пул соединений, связанный с конкретным соединением.Если во время вызова используются соединения, они помечаются соответствующим образом.Когда они закрыты, они сбрасываются, а не возвращаются в пул.

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