【问题标题】:How to use TransactionScope in C#?如何在 C# 中使用 TransactionScope?
【发布时间】:2009-04-27 16:54:53
【问题描述】:

我正在尝试使用TransactionScope,但不断收到以下异常。
该应用程序运行在与数据库不同的机器上,如果这很重要的话。我使用的是 SQL Server 2005。

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

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

编辑

我根据反馈做了一些更改。现在我收到此错误:

“调用 COM 组件返回了错误 HRESULT E_FAIL。”
“与底层事务管理器的通信失败。”

解决方案 我认为接受的答案解决了我遇到的最初问题。第二个错误似乎特定于实体框架。我将为此发布另一个问题。

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

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

【问题讨论】:

  • NotDan 你还有链接到的图像到处跑吗?如果是这样,最好重新发布它们以修复它们当前已损坏的图像引用这一事实。

标签: c# .net database transactions transactionscope


【解决方案1】:

您需要按照Microsoft TechNet Article 中的说明启用网络 DTC 访问。可能必须在数据库和应用程序服务器上都进行此更改。很多时候 DTC 已经打开了数据库服务器,所以我会先查看应用程序服务器。

以下是我们使用的屏幕截图,但“允许远程管理”选项除外:

我没有遇到您现在遇到的 HRESULT E_Fail 问题,但XP SP2 and transactions 上的这篇文章有一个有趣的建议:

另一个配置设置 需要注意(虽然我认为 这是一个不常见的情况)是 RestrictRemoteClients 注册表项。如果 此键的值设置为 2 (RPC_RESTRICT_REMOTE_CLIENT_HIGH) 然后 MSDTC 网络交易不会 能够正常工作。 MSDTC 支持 只有 RPC_RESTRICT_REMOTE_CLIENT_NONE (0) 和 RPC_RESTRICT_REMOTE_CLIENT_DEFAULT (1) 价值观。看 http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx#XSLTsection128121120120 有关更多信息 限制远程客户端。

最后,虽然不是针对您的问题,但关于使用TransactionScope 类的一个非常重要的注意事项是,它的默认设置是使用Transaction Isolation Level of Serializable。 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 文章可能适用。
  • 我认为这解决了我遇到的最初问题。第二个错误似乎特定于实体框架。我会为此发布另一个问题。
  • 我终于解决了这个问题。 Windows 防火墙阻止了与 MS-DTC 的连接。
  • 我什么时候应该为数据库和应用程序服务器同时启用它?
  • @katherine 我已经很多年没有弄乱 DTC 了,但如果我记得它需要同时打开应用程序和数据库服务器。只是它通常已经打开了数据库服务器,所以不需要更改。
【解决方案2】:

控制面板 - 管理工具 - 组件服务 - 我的电脑属性 - MSDTC 选项卡 - 安全配置选项卡 - 网络 DTC 访问(选中)/允许远程客户端(选中)/允许入站(选中)/允许出站(选中)/启用提示交易(选中)

重启电脑。

【讨论】:

    【解决方案3】:

    根据您使用的后端,TransactionScope 通常需要启用分布式事务管理器。一些细节是on this MSDN blog

    此外,如果您使用多个资源,则可能需要 DTC。在您的情况下可能需要启用 DTC,或者确保您使用的是 SQL Server 2005 并坚持在轻量级事务中可行的方法。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        如果您使用的是 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
        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

          我发布了一个关于这个here的问题

          但最终我找到了解决方法。虽然,我不建议对生产代码这样做。我是在测试的背景下做的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多