.NET 中的嵌套事务

发布于 2024-11-28 07:04:07 字数 1542 浏览 2 评论 0原文

我怎样才能执行与此等效的操作? 我的理解是,这对于 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 来指示我想要做什么,并且正在寻找实现此功能的最佳替代方法。

How can I perform the equivalent of this? My understanding is that this is impossible with TransactionScopes but I'd like to accomplish the equivalent in some other way:

Business Logic class:

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;
}

Now this works fine, until I encapsulate all of this inside of a transaction (perhaps an integration test that I want to rollback after performing asserts).

Simple test to prove my point:

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.

  }
}

Ultimately, the code in Foo.Bar() can be modified to accommodate a solution however, the code in ComplicatedDataImportCode() cannot be modified for this solution, and is consequently what I really need to make sure I properly rollback in the failure scenario.

Again, I understand that TransactionScopes cannot be used to do this, according to the post that I referenced at the beginning of this question. I used TransactionScopes here to indicate what I wanted to do, and am looking for the best alternative way to implement this functionality.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如日中天 2024-12-05 07:04:07

是不是您正在使用的 DBMS 必须支持这一点?

例如,SQL Server 并不真正支持嵌套事务,但是,对于 SQL Server,您可以使用 保存点

一篇文章我几年前写的在我的博客上。

Isn't it so that this must be supported by the DBMS you're using ?

SQL Server doesn't really support nested transactions for instance, however, with SQL Server you can use savepoints.

An article I've written some years ago on my blog.

九厘米的零° 2024-12-05 07:04:07

如果您可以获取 ComplicatedDataImportCode 正在使用的活动数据库连接,则只需运行 BEGIN TRANROLLBACK TRAN 即可那个连接。

If you can get a hold of the active DB connection that ComplicatedDataImportCode is using, you should just have to run a BEGIN TRAN and ROLLBACK TRAN on that connection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文