如何在C#中使用TransactionScope?

38

我正在尝试使用TransactionScope,但不断收到下面的异常。
如果有影响,该应用程序正在运行于与数据库不同的计算机上。 我正在使用SQL Server 2005。

已禁用分布式事务管理器(MSDTC)的网络访问。 请使用组件服务管理工具为MSDTC在安全配置中启用网络访问的DTC。

using (TransactionScope tsTransScope = new TransactionScope())
{
    //Do stuff here
    tsTransScope.Complete();
}

编辑

我根据反馈做出了一些更改,现在我遇到了这个错误:

"Error HRESULT E_FAIL has been returned from a call to a COM component."
"Communication with the underlying transaction manager has failed."

解决方法 我认为被接受的答案解决了我最初遇到的问题。第二个错误似乎是与Entity Framework相关的。我将发布另一个问题来解决它。

以下是客户端上的属性:
客户端 http://www.portnine.com/data/images/Misc/client.jpg

以下是服务器上的属性:
服务器 http://www.portnine.com/data/images/Misc/server.jpg


NotDan,你还有之前链接的那些图片吗?如果有的话,重新发布它们会很好,因为它们目前是无法显示的。 - ahsteele
7个回答

34
你需要按照Microsoft TechNet文章中的描述启用网络DTC访问。这个更改可能需要在数据库和应用程序服务器上同时进行。通常情况下,数据库服务器已经开启了DTC,所以我会先查看应用程序服务器。
这是我们使用的屏幕截图,除了"允许远程管理"选项: Security Configuration Screenshot 我没有遇到你现在正在遇到的HRESULT E_Fail问题,但XP SP2和事务这篇文章提出了这个有趣的建议:
另一个需要注意的配置设置(尽管我认为这是不常见的情况)是RestrictRemoteClients注册表键。如果此键的值设置为2(RPC_RESTRICT_REMOTE_CLIENT_HIGH),则MSDTC网络事务将无法正常工作。MSDTC仅支持RPC_RESTRICT_REMOTE_CLIENT_NONE(0)和RPC_RESTRICT_REMOTE_CLIENT_DEFAULT(1)值。有关RestrictRemoteClients的更多信息,请参见http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx#XSLTsection128121120120
最后,虽然与您的问题无关,但有一件非常重要的事情需要注意,那就是使用TransactionScope类的默认设置是使用可序列化的Transaction Isolation Level。Serializable是隔离级别中最严格的,而且令人惊讶的是它被选为默认值。如果您不需要这种级别的锁定,则强烈建议在实例化TransactionScope时将隔离级别设置为较不严格的选项(ReadCommitted):
var scopeOptions = new TransactionOptions();
scopeOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
scopeOptions.Timeout = TimeSpan.MaxValue;

using (var scope = new TransactionScope(TransactionScopeOption.Required,
    scopeOptions))
{
    // your code here
}

我从你的截图中看出你没有使用XP,但我认为XP SP2的文章可能适用。 - ahsteele
我认为这解决了我一开始遇到的问题。第二个错误似乎是特定于实体框架的。我会发另一个问题来询问它。 - NotDan
3
我终于解决了这个问题。Windows防火墙一直在阻止与MS-DTC的连接。 - NotDan
我应该在什么时候同时为数据库和应用服务器打开它? - Katherine
@katherine 我已经很多年没有涉及DTC了,但如果我记得正确的话,它需要在应用程序和数据库服务器上都打开。通常情况下,数据库服务器已经打开了它,因此不需要进行任何更改。 - ahsteele

3

控制面板 - 管理工具 - 组件服务 - 计算机属性 - MSDTC 选项卡 - 安全配置选项卡 - 启用网络DTC访问(已勾选)/ 允许远程客户端(已勾选)/ 允许入站(已勾选)/ 允许出站(已勾选)/ 启用TIP事务(已勾选)

重新启动计算机。


2
根据您所使用的后端,TransactionScope通常需要启用分布式事务管理器。有关详细信息,请参阅此MSDN博客
此外,如果您使用多个资源,则可能需要DTC。在您的情况下,需要启用DTC或确保您正在使用SQL Server 2005并坚持在轻量级事务中可行的操作。

1

您需要使用组件服务管理工具,在 MSDTC 的安全配置中启用 DTC 以进行网络访问。


0
如果您正在使用 SQL Server 2000,则System.Transactions.TransactionScope将导致所有事务升级为分布式事务,需要运行MS分布式事务协调器。
您可以通过启动MSDTC服务、升级到SQL Server 2005或实现类似我的codeproject解决方案http://www.codeproject.com/KB/database/typed_dataset_transaction.aspx来解决此问题。
我从未需要这样做,但您还应该检查Ocdecio的答案以配置DTC的网络安全设置。

在此添加一条注释,我正在使用 Sql Server 2005。 - NotDan

0

在数据库服务器和应用程序运行的服务器上,您需要启用网络DTC访问。

您还需要确认连接不会被防火墙阻止。由于连接将从数据库服务器发起到应用程序机器,因此同样重要的是将MSDTC添加到应用程序机器的防火墙例外列表中。


0

我在运行集成测试时遇到了同样的问题。

我在这里发布了一个关于此问题的问题。

但最终我找到了一个解决方法。虽然,我不建议在生产代码中这样做。我是在测试环境下进行的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接