【问题标题】:Rolling back transaction scope C#回滚事务范围 C#
【发布时间】:2015-10-12 06:38:20
【问题描述】:

为了进一步专业化我们的测试方法,我正在使用 Visual Studio 中的单元测试框架进行一些集成测试。

被测对象是一个 WCF 服务,我的小应用使用 ServiceHost 在内存中运行该服务,并且我能够调用测试中公开的方法。

这一切都很好,但我希望能够在使用 Transactions 进行测试后恢复数据库。为了实现这一点,我在被测方法中添加了 TransactionScopeRequired 属性,并尝试在 TransactionScope 中调用它。

但后来我注意到 TransactionScope 没有内置的回滚方法,所以在方法完成后,创建的对象当然还在数据库中。

所以我尝试不使用“完成”方法,经过一番谷歌搜索后,我发现手动使用 Dispose 应该回滚事务。唉,两者都不起作用。所以我继续启动 SQL Server Analyzer 来查看生成的 SQL,也许我可以在其中找到一些 TRANSACTION 语句。

我注意到的第一件事是所有相关查询都作为存储过程(由 EF 生成)执行。第二件事是我无法区分相关查询中的任何类型的事务管理。

现在我的问题:无论好坏,这可以在这个层面上解决吗?如果有怎么办?是否可以使用这样的“外部”交易?

【问题讨论】:

  • 有一个问题:你只使用一层事务吗? (根据经验,当您在交易中进行交易时会变得非常复杂,因为您需要启用远程交易才能使其正常工作)
  • 另请注意,如果您回滚事务,则不会重置您的身份列从自动生成中获取的值,即您不能真正根据测试中正确生成的 id 进行假设。跨度>

标签: c# sql-server entity-framework wcf transactions


【解决方案1】:

要回滚事务,您可以:

  1. 致电Transaction.Current.Rollback();
  2. 不打电话Transaction.Complete();

在服务器端检查,Transaction.Current 不为空。所以你会知道你是否有一个当前的交易

允许 Tx :

  1. 关于接口方法:

    [运营合同]
    [TransactionFlow(TransactionFlowOption.Allowed)]
    public void Method(int value);

  2. 关于服务端方法实现:

    [操作行为(TransactionScopeRequired=true, TransactionAutoComplete=true)]
    公共无效方法(int值){...}

  3. 在绑定允许事务流,在客户端和服务器端:

附代码:

var wsHttpBinding = new WsHttpBinding();
wsHttpBinding.TransactionFlow = true;

或使用 XML:

<endpoint address="wsHttpTx" binding="wsHttpBinding" 
    contract="counters.ICountersService" 
    bindingConfiguration="wsHttpTx"/>
   ...
<wsHttpBinding>
  <binding name="wsHttpTx" transactionFlow="true" />
</wsHttpBinding>

问候

【讨论】:

    【解决方案2】:

    据我了解您的问题: 1)您尝试使用事务范围在测试方法中打开新事务 2)您在此事务范围内调用 WCF 服务 3) 您的服务进行了一些数据库更改。

    要回滚更改,您根本不应该调用事务范围的 Complete 方法。我总是很高兴在using 中创建 Transaction 范围,以便最终自动 Dispose。

    所以现在您的服务应该支持来自客户端的事务传播。查看相同的问题 (Calling WCF service method from transaction scope) 并阅读 MSDN 文章 (https://msdn.microsoft.com/en-us/library/ms730250.aspx)

    注意:有几篇文章-How to enable transactionsHow to configure service

    但老实说,如果真正的客户端没有真正的要求来支持事务,并且在传输/消息/序列化程序级别上没有一些 WCF 特定的自定义,比如 WCF 拦截器,那么老实说,我做所有这些只是为了让测试事务化是多余的。 我要么直接测试服务类,而不运行服务主机,要么创建某种 TearDown 清理,并在测试后手动恢复数据库状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-14
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      相关资源
      最近更新 更多