Использование TransactionScope не приводит к повторному заполнению столбца идентификаторов - PullRequest
3 голосов
/ 07 июня 2011

Я начал использовать TransactionScope , чтобы помочь с моими модульными тестами, чтобы вернуть мою тестовую базу данных в прежнее состояние.Используя это с SpecFlow, у меня есть базовый класс, например, так:

public class TransactionScopedFeature
{
    private TransactionScope Scope { get; set; }

    [BeforeScenario]
    public void BaseSetup()
    {
        this.Scope = new TransactionScope(TransactionScopeOption.RequiresNew);
    }

    [AfterScenario]
    public void BaseCleanup()
    {
        if (this.Scope != null)
        {
            this.Scope.Dispose();
        }
    }
}

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

Мой вопрос касается столбцов идентификации в этих таблицах.Что я заметил, так это то, что, когда я запускаю свои тесты много раз, столбец ID моей тестовой таблицы увеличивается на 1. Я предполагал, что, поскольку TransactionScope будет выполнять откат изменений, начальное число идентификаторов также будет откатываться.

Я ошибаюсь, когда делаю это предположение - так ли это работают базы данных?Если это так, я мог бы также запустить сценарий SQL перед каждым из моих сценариев, который делает это:

DBCC CHECKIDENT ('dbo.Items', reseed, 0)

Я просто хотел проверить, не делал ли я что-то не так,или это нормальное поведение базы данных.

Приветствия.Иак.

Ответы [ 2 ]

7 голосов
/ 07 июня 2011

Начальное значение для столбца идентификации не откатывается с остальной частью транзакции в SQL Server.

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

2 голосов
/ 11 апреля 2012

Повторная идентификация после отката может быть очень опасной: если другая транзакция вставит запись, произойдет коллизия идентификаторов.

Например

  1. Вы начинаете транзакцию
  2. Вы вставляете запись в таблицу t: поле идентификатора установлено в 10
  3. Джон, в другой параллельный клиент вставьте запись в таблицу t. Поскольку первая транзакция не зафиксировала и не произвела откат, для идентификатора транзакции Джона установлено значение 11
  4. Джон совершает свою транзакцию. Запись с id = 11 сохраняется
  5. Откат транзакции
  6. Вы переустановили идентичность к предыдущему значению, то есть 9
  7. Вы вставили 2 новые записи. Второй будет иметь id = 11, с соответствующим столкновением идентификаторов

Это может произойти, особенно если ваши интеграционные тесты unit выполняются параллельно (это очень распространенное поведение в NCrunch).

Правило большого пальца: не повторять после отката

Также см. Ответ marc_s дал этот вопрос

...