Вложенные транзакции в .NET - PullRequest
7 голосов
/ 08 августа 2011

Как я могу выполнить эквивалент этого? Насколько я понимаю, это невозможно с TransactionScopes , но я бы хотел сделать эквивалент другим способом:

Класс бизнес-логики:

public bool Bar()
{
  try
  {
    using (var tsWork = new TransactionScope())
    {
      ComplicatedDataImportCode(somedata);
      FlagRecordInDatabaseAsImported(); // this is the same record that's modified in the catch
      tsWork.Complete();
      return true;
    }
    catch (DuplicateDataException err)
    {
      // if we got here, the above transaction should have rolled back,
      // so take that same record in the database and update it to "Duplicate".
      FlagSameRecordInDatabaseAsDuplicate(err.Message);
    }

    return false;
}

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

Простой тест, чтобы доказать мою точку зрения:

public void CanTest()
{
  // Arrange
  var foo = new Foo();

  using (var ts = new TransactionScope())
  {
    // Act
    var success = foo.Bar();

    // Assert
    if (success)
    {
      Assert.That(SomethingThatTestsThatTheDataWasImported);
    }
    else
    {
      Assert.That(SomethingThatTestsThatTheRecordWasMarkedAsDuplicate);
    }

    // Now that we have been able to perform our Asserts, rollback.

  }
}

В конечном счете, код в Foo.Bar() можно изменить, чтобы приспособить решение, однако код в ComplicatedDataImportCode() не может быть изменен для этого решения, и, следовательно, мне действительно нужно убедиться, что я правильно откатился в сценарии сбоя .

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

Ответы [ 2 ]

2 голосов
/ 08 августа 2011

Не правда ли, что это должно поддерживаться используемой СУБД?

Например, SQL Server на самом деле не поддерживает вложенные транзакции, однако с SQL Server вы можете использовать точки сохранения .

Статья Я написал несколько лет назад в своем блоге.

1 голос
/ 08 августа 2011

Если вы можете получить активное соединение с БД, которое использует ComplicatedDataImportCode, вам просто нужно запустить BEGIN TRAN и ROLLBACK TRAN для этого соединения.

...