回滚事务范围 C#
Rolling back transaction scope C#
为了进一步专业化我们的测试方法,我正在使用 Visual Studio 中的单元测试框架进行一些集成测试。
被测对象是一个 WCF 服务,我的小应用程序使用 ServiceHost 在内存中运行该服务,我能够调用测试中公开的方法。
一切正常,但我希望能够在测试后使用事务恢复数据库。为了实现这一点,我将 TransactionScopeRequired 属性添加到被测方法,并尝试在 TransactionScope 中调用它。
但后来我注意到 TransactionScope 没有内置的回滚方法,所以在该方法完成后,创建的对象当然仍在数据库中。
所以我尝试不使用 'Complete' 方法,经过一些谷歌搜索后我发现只需手动使用 Dispose 就应该回滚事务。 las,都没有用。所以我继续启动 SQL 服务器分析器来查看生成的 SQL,也许我可以在其中找到一些 TRANSACTION 语句。
我注意到的第一件事是所有相关查询都作为存储过程(由 EF 生成)执行。第二件事是我无法在相关查询中区分任何类型的事务管理。
现在我的问题:无论是好是坏,这个问题可以在这个层面上解决吗?如果是这样怎么办?是否可以使用这样的 'external' 交易?
要回滚事务,您可以:
- 致电
Transaction.Current.Rollback();
- 不打电话
Transaction.Complete();
检查服务器端,Transaction.Current 不为空。所以你会知道你是否有当前交易
允许Tx :
关于界面方法:
[操作合约]
[事务流(TransactionFlowOption.Allowed)]
public无效方法(整数值);
关于服务器方法实现:
[OperationBehavior(TransactionScopeRequired=true,
TransactionAutoComplete=true)]
public void Method(int value) { ... }
关于客户端和服务器端的绑定允许事务流:
使用代码:
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>
此致
据我了解你的问题:
1)您尝试使用事务范围在测试方法中打开新事务
2) 您在此事务范围内调用 WCF 服务
3) 您的服务做了一些数据库更改。
要回滚更改,您根本不应该调用事务范围的 Complete 方法。我总是善于在 using
中创建事务范围,以便在最后自动处理。
所以现在您的服务应该支持来自客户端的事务传播。见同题(Calling WCF service method from transaction scope) and read MSDN articles (https://msdn.microsoft.com/en-us/library/ms730250.aspx)
注:有几篇-How to enable transactions , How to configure service
但老实说,如果真正的客户端没有真正要求支持事务并且没有某些 Transport/message/serializer 级别的 WCF 特定定制(如 WCF 拦截器),那么对我来说只做所有这些只是为了测试事务是过大的。 我会直接测试服务 class,没有 运行 服务主机,或者创建某种 TearDown 清理并在测试后手动恢复数据库状态。
为了进一步专业化我们的测试方法,我正在使用 Visual Studio 中的单元测试框架进行一些集成测试。
被测对象是一个 WCF 服务,我的小应用程序使用 ServiceHost 在内存中运行该服务,我能够调用测试中公开的方法。
一切正常,但我希望能够在测试后使用事务恢复数据库。为了实现这一点,我将 TransactionScopeRequired 属性添加到被测方法,并尝试在 TransactionScope 中调用它。
但后来我注意到 TransactionScope 没有内置的回滚方法,所以在该方法完成后,创建的对象当然仍在数据库中。
所以我尝试不使用 'Complete' 方法,经过一些谷歌搜索后我发现只需手动使用 Dispose 就应该回滚事务。 las,都没有用。所以我继续启动 SQL 服务器分析器来查看生成的 SQL,也许我可以在其中找到一些 TRANSACTION 语句。
我注意到的第一件事是所有相关查询都作为存储过程(由 EF 生成)执行。第二件事是我无法在相关查询中区分任何类型的事务管理。
现在我的问题:无论是好是坏,这个问题可以在这个层面上解决吗?如果是这样怎么办?是否可以使用这样的 'external' 交易?
要回滚事务,您可以:
- 致电
Transaction.Current.Rollback();
- 不打电话
Transaction.Complete();
检查服务器端,Transaction.Current 不为空。所以你会知道你是否有当前交易
允许Tx :
关于界面方法:
[操作合约]
[事务流(TransactionFlowOption.Allowed)]
public无效方法(整数值);关于服务器方法实现:
[OperationBehavior(TransactionScopeRequired=true, TransactionAutoComplete=true)]
public void Method(int value) { ... }关于客户端和服务器端的绑定允许事务流:
使用代码:
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>
此致
据我了解你的问题: 1)您尝试使用事务范围在测试方法中打开新事务 2) 您在此事务范围内调用 WCF 服务 3) 您的服务做了一些数据库更改。
要回滚更改,您根本不应该调用事务范围的 Complete 方法。我总是善于在 using
中创建事务范围,以便在最后自动处理。
所以现在您的服务应该支持来自客户端的事务传播。见同题(Calling WCF service method from transaction scope) and read MSDN articles (https://msdn.microsoft.com/en-us/library/ms730250.aspx)
注:有几篇-How to enable transactions , How to configure service
但老实说,如果真正的客户端没有真正要求支持事务并且没有某些 Transport/message/serializer 级别的 WCF 特定定制(如 WCF 拦截器),那么对我来说只做所有这些只是为了测试事务是过大的。 我会直接测试服务 class,没有 运行 服务主机,或者创建某种 TearDown 清理并在测试后手动恢复数据库状态。