2015-10-29 2 views
1

У меня есть интеграционный тест, который выглядит следующим образом:.Net/SQL гонки сервера состояние

[TestMethod] 
    public async Task TestMethod1() 
    { 
     Guid guid = Guid.NewGuid(); 

     using (HttpClient client = new HttpClient()) 
      await client.GetAsync(String.Format(_uri, guid.ToString())); 

     Guid retrieved = GetLastGuid(); 
     Assert.AreEqual(guid, retrieved); 
    } 

client.GetAsync взывает к простой веб-сервис, который экономит Guid в таблице базы данных. GetLastGuid выполняет следующий запрос на стол:

select top 1 * from dbo.Messages order by MessageId desc

Где идентификатор сообщения является столбцом идентификаторов на таблице сообщений.

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

Что я ожидаю случаться

Служба является вызываемой и Guid сохраняется в базу данных. Поиск последней строки в таблице базы данных приведет к возврату последней записи. Мое понимание (и где я подозреваю, что я ошибаюсь) заключается в том, что выполнение хранимых процедур на SQL-сервере является синхронным процессом, т. Е. Он не вернется, пока не совершит транзакцию.

Что на самом деле происходит

Цепной несколько вызовов к моим результатам методы испытаний в некоторых из них не удаются. Похоже, что они извлекают Guid для предыдущего вызова.

То, что я думаю, что может быть причиной

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

Все методы тестирования запускаются последовательно, и ничто другое не записывает в эту таблицу базы данных. Разумное использование Thread.Sleep/running в режиме отладки разрешает проблему, все классические признаки состояния гонки.

+0

Что произойдет, если вы не используете область использования? – Menahem

+0

, если указатель в вашем коде является [UNIQUEIDENTIFIER] (https://msdn.microsoft.com/en-us/library/ms187942%28v=sql.120%29.aspx) на SQL, тогда имейте в виду, что эти идентификаторы не являются последовательными, поэтому вы не можете заказать руководство, чтобы получить самую последнюю. – Paolo

ответ

1

select top 1 не гарантирует, что вы дадите правильное руководство. Вы должны указать, чтобы выбрать * из dbo.Messages где guid = @guid или вернуть messageid (?) Из клиентского вызова http и использовать это для извлечения данных и сравнения их. Хотя если никакие данные не возвращаются, это должно быть первое подтверждение, которое нужно проверить.