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