我怎样才能做到这一点呢? My understanding is that this is impossible with 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来指示我想做的事情,并且正在寻找实现此功能的最佳替代方法。

最佳答案

难道不是您正在使用的DBMS必须支持此功能吗?

例如,SQL Server并不真正支持嵌套事务,但是,使用SQL Server可以使用savepoints

An article我几年前在博客上写过。

10-04 21:52