SQL Server и TransactionScope (с MSDTC): время от времени не удается получить соединение - PullRequest
2 голосов
/ 19 июня 2010

Я написал несколько тестов для кода .net, который вызывает вызовы к моему SQL Server. Похоже, что использование System.Transactions является отличным выбором для отката любых изменений в базе данных, которые в результате. Я знаю, что некоторые пуристы предложат мне издеваться над базой данных, но я не иду по этому пути; это не совсем чистый юнит-тест.

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

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

Как многие из вас знают, использование TransactionScope в коде, который выполняется на рабочей станции разработки (как при выполнении этого теста) на сервере SQL, заставит .net framework использовать MSDTC.

Вот пример кода для иллюстрации того, что я делаю:

 <TestInitialize()> Public Sub MyTestInitialize()
    _scope = New System.Transactions.TransactionScope( _
        System.Transactions.TransactionScopeOption.Required, New TimeSpan(0, 2, 0))
End Sub
<TestCleanup()> Public Sub MyTestCleanup()
    _scope.Dispose()
End Sub

<TestMethod()> Public Sub CurrentProgramUser_Get_UserID()
    Dim ProgramSessionId As String
    Dim CurrentProgramUserId As Integer
    Dim dSession As ProgramSession
    CurrentDCMAUserId = Convert.ToInt32( _
    SqlHelper.ExecuteScalar(testDcmaConnString, System.Data.CommandType.Text, _
    "INSERT into Program_Users(UserName,FirstName,LastName) " & _
    "VALUES('GuitarPlayer','Bob','Marley')" & _
    "SELECT IDENT_CURRENT('Program_users') ") _
                         )
    ProgramSessionId = session.getCurrentSession()
    session.WriteUserParam("Program", ProgramSessionId, "USERID", CurrentProgramUserId.ToString(), testSource, testConnString)

    Dim readValue As Integer
    readValue = session.User.UserID

    Assert.AreEqual(CurrentProgramUserId, readValue)
End Sub

Как видите, здесь нет ничего особенного. У меня просто есть тестовый метод, который собирается записать некоторые вещи в мою базу данных, которые я хочу, чтобы мой метод нашел. Это только один пример; Есть много других тестов, подобных этому.

Логика моих тестов, похоже, правильная. Что может быть причиной того, что мои тесты не только не срабатывают, но и время от времени блокируют пользователей из таблиц?

1 Ответ

2 голосов
/ 21 июня 2010

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

Просто добавив mySqlDataReader.Close() кКонец тестируемого метода устранил проблему.Кроме того, метод тестирования для тестирования этого конкретного метода был основан на данных с более чем 100 тестовыми примерами, поэтому это объясняет, как у меня могли закончиться соединения.

...