【问题标题】:Use of TransactionScope with Databases in C#在 C# 中将 TransactionScope 与数据库一起使用
【发布时间】:2016-02-24 17:57:06
【问题描述】:

考虑下面给出的示例代码片段。

当我最后不写transaction.Complete(); 时,对数据库所做的更改是否会恢复?

   using (var transaction = new System.Transactions.TransactionScope())
    {

      var database = new DatabaseContext();

      var userA = database.Users.Find(1);

      var userB = database.Users.Find(2);
      userA.Name = "Admin";

      database.SaveChanges();
      userB.Age = 28;
      database.SaveChanges();
      transaction.Complete(); // Do changes done by database.saveChanges(); gets reverted if this statement is ommited ? 
}

提前致谢。

【问题讨论】:

  • 这真的很容易测试。注释掉这一行,看看会发生什么
  • 为什么要问这个问题?注释掉该行应该证明回滚有效。你遇到过不同的行为吗?这背后还有其他问题吗?
  • 有关完整说明,请查看 MSDN at the method

标签: c# .net transactionscope


【解决方案1】:

是的。

但是你为什么需要它?在给定的示例中,一个简单的数据库上下文可以满足您的要求。

如果您不调用database.SaveChanges(),下次数据库将在该特定位置打开新连接时,它将不包含旧数据。

我对事务范围有点谨慎...

【讨论】:

  • 以上代码仅用于说明目的。我正在为框架编写测试方法。测试完成后需要立即清理写入数据库的数据。我认为将测试方法包装在 Transaction Scope 中是一种很好的方法,而不是在 Test Cleanup 方法中清理数据。欢迎任何进一步的意见和建议。 :)
  • 但是,这就是我的意思。你真的不需要事务范围,数据库上下文就可以了。好吧,这取决于您遵循的方法。当我在同一个逻辑流中创建多个数据库上下文(错误的方法)时,我需要使用事务范围 1 或 2 次。
  • 我也是这种情况。我的测试方法使用多个数据库上下文,它会修改这些上下文中的数据。事务范围将负责处理这些多个上下文。
  • 在这种情况下,这是唯一的选择。但请记住,使用多个上下文不是正确的方法。但这在很大程度上取决于您使用的平台/技术(mvc、表单等)。您始终可以实现“每个请求的上下文”方法,每个请求只有一个上下文。如果您不执行 savechanges,它将不会保存任何内容,如果两次 savechanges 之间发生异常,您的方法(无事务)可能会发生这种情况。
【解决方案2】:

是的。

从这里...

// The Complete method commits the transaction. If an exception has been thrown,
        // Complete is not  called and the transaction is rolled back.
        scope.Complete();

https://msdn.microsoft.com/en-us/library/ee818746%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 2014-12-18
    相关资源
    最近更新 更多