【问题标题】:TransactionScope Error against Sql Server 2000 - The partner transaction manager has disabled its support for remote/network transactions针对 Sql Server 2000 的 TransactionScope 错误 - 合作伙伴事务管理器已禁用其对远程/网络事务的支持
【发布时间】:2008-11-26 15:00:33
【问题描述】:

我正在尝试针对我的 Sql 2000 数据库为我的 Linq-to-Sql 操作设置一个简单的事务。使用 TransactionScope 它看起来像这样:

using (TransactionScope transaction = new TransactionScope())
{
    try
        {
        Store.DBDataContext dc = new Store.DBDataContext();
        Store.Product product = GetProduct("foo");
        dc.InsertOnSubmit(product);
        dc.SubmitChanges();
        transaction.Complete();
    }
    catch (Exception ex)
    {                
        throw ex;
    }
}

但是,我不断收到以下错误:

合作伙伴事务管理器已禁用对远程/网络事务的支持。 (HRESULT 异常:0x8004D025)

但是,如果我使用传统交易设置交易,它可以正常工作。所以这很好用:

Store.DBDataContext dc = new Store.DBDataContext();
try
{
    dc.Connection.Open();
    dc.Transaction = dc.Connection.BeginTransaction();
    Store.Product product = GetProduct("foo");
    dc.InsertOnSubmit(product);
    dc.SubmitChanges(); 
    dc.Transaction.Commit();
}
catch (Exception ex)
{
    dc.Transaction.Rollback();
    throw ex;
}
finally
{
    dc.Connection.Close();      
    dc.Transaction = null;
}

我想知道 TransactionScope 在幕后做的事情是否与我的第二个实现不同。如果没有,我不使用 TransactionScope 会失去什么?此外,有关导致错误的原因的任何指导也很好。我已经确认 MSDTC 正在 sql server 和我的客户端计算机上运行。

【问题讨论】:

    标签: linq-to-sql transactions transactionscope msdtc


    【解决方案1】:

    看这里:

    使用 System.Transactions 和 Microsoft SQL Server 2000 进行快速事务 http://blogs.msdn.com/florinlazar/archive/2005/09/29/475546.aspx

    在这里:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=230390&SiteID=1

    首先验证“分发事务协调器”服务是 在数据库服务器计算机和客户端计算机上运行
    1. 转到“管理工具 > 服务”
    2. 如果“Distribute Transaction Coordinator”服务没有运行,请开启它

    如果它正在运行并且客户端应用程序不在同一台计算机上 数据库服务器,在运行数据库服务器的计算机上
    1. 转到“管理工具 > 组件服务”
    2.在左侧导航树中,进入“组件服务>计算机>我的电脑”(部分节点可能需要双击等待 需要时间来扩展)
    3. 右击“我的电脑”,选择“属性”
    4. 选择“MSDTC”标签
    5. 点击“安全配置”
    6. 确保选中“网络 DTC 访问”、“允许远程客户端”、 “允许入站/出站”、“启用 TIP”(某些选项可能不会 有必要,请尝试获取您的配置)
    7.服务将重启
    8.但如果仍然无法正常工作,您可能需要重新启动服务器 (这就是之前让我发疯的事情)

    在您的客户端计算机上使用与上述相同的过程打开 “安全配置”设置,确保选中“网络 DTC” 访问”,“允许入站/出站”选项,重新启动服务和计算机 如有必要。

    在您的 SQL Server 服务管理器上,单击“服务”下拉菜单,选择 “分发事务协调器”,它也应该运行在 您的服务器计算机。

    【讨论】:

    • Florin Lazar 帖子中引用的 DatabaseTransactionAdapter 起到了作用。我将发布我的实现代码作为回复。
    • 配置 MSDTC 的说明似乎不适用于 windows 7 我在 MSDTC 选项卡下只有一个选项:使用本地协调器或指定要使用的远程主机。
    • 我找到了在 Windows 7 和 2008 上查找这些设置的说明!看这里:msdn.microsoft.com/en-us/library/aa561924(BTS.20).aspx
    【解决方案2】:

    Keith Sirmons 向我指出的 Florin Lazar 帖子中的 DatabaseTransactionAdapter 实现似乎可以解决问题。这是我调用它的代码:

    Store.DBDataContext dc = new Store.DBDataContext();
    using (TransactionScope transaction = new TransactionScope())
    {
        try
        {
            var dbAdapter = new DatabaseTransactionAdapter(dc.Connection);
            dc.Connection.Open();
            dbAdapter.Begin();
            dc.Transaction = (SqlTransaction)dbAdapter.Transaction;
            Store.Product product = GetProduct("foo");
            dc.InsertOnSubmit(product);
            dc.SubmitChanges();
            transaction.Complete();
        }
        catch (Exception ex)
        {                
            throw ex;
        }
    }
    

    唯一让我不安的是,我没有明确关闭连接,即使它没有在“使用”语句中声明。

    但根据 Florin Lazar 的说法,这是故意的。

    而且你也不能关闭 连接,因为连接 应该保持开放直到交易 完成,这发生在 “使用”语句结束。适配器 将拥有连接的所有权 生命周期并在完成后关闭它 用它。

    【讨论】:

      【解决方案3】:

      在 Windows 2008 或更高版本上启用此功能的步骤如下:

      首先验证“分发事务协调器”服务是 在数据库服务器计算机和客户端计算机上运行

      1. 转到“管理工具 > 服务”
      2. 如果“分发事务协调器”服务未运行,请打开它

      如果它正在运行并且客户端应用程序不在同一台计算机上 数据库服务器,在运行数据库服务器的计算机上

      1. 转到“管理工具 > 组件服务”
      2. 在左侧导航树中,进入“组件服务 > 计算机 > 我的电脑 > 分布式事务协调器”(可能需要双击等待,因为有些节点需要时间展开)
      3. 右键单击“本地 DTC”,选择“属性”
      4. 选择“安全”标签
      5. 确保选中“网络 DTC 访问”、“允许远程客户端”、“允许入站/出站”
      6. 服务将重新启动
      7. 但是如果仍然无法正常工作,您可能需要重新启动您的服务器(这是之前让我发疯的事情)

      在您的客户端计算机上使用 同上程序打开“安全配置”设置, 确保选中“网络 DTC 访问”、“允许入站/出站” 选项,必要时重启服务和计算机。

      在您的 SQL 服务器上 服务管理器,点击“服务”下拉菜单,选择“分发” 事务协调器”,它也应该在您的服务器上运行 电脑。

      【讨论】:

        【解决方案4】:

        我在这里发布以下解决方案,因为经过一番搜索,这是我登陆的地方,所以其他人也可以。我尝试使用 EF 6 调用存储过程,但由于存储过程使用了链接服务器,因此出现了类似错误。

        无法执行该操作,因为用于链接服务器的 OLE DB 提供程序 _ 无法开始分布式事务

        合作伙伴事务管理器已禁用对远程/网络事务的支持

        跳转到 SQL 客户端 确实解决了我的问题,这也向我证实了这是一个 EF 问题。

        EF 模型生成基于方法的尝试:

        db.SomeStoredProcedure();
        

        基于 ExecuteSqlCommand 的尝试:

        db.Database.ExecuteSqlCommand("exec [SomeDB].[dbo].[SomeStoredProcedure]");
        

        与:

        var connectionString = db.Database.Connection.ConnectionString;
        var connection = new System.Data.SqlClient.SqlConnection(connectionString);    
        var cmd = connection.CreateCommand();
        cmd.CommandText = "exec [SomeDB].[dbo].[SomeStoredProcedure]";
        
        connection.Open();
        var result = cmd.ExecuteNonQuery();
        

        该代码可以缩短,但我认为该版本更便于调试和单步执行。

        我不认为 Sql Client 一定是首选,但我觉得如果有类似问题的其他人被谷歌登陆这里,至少值得分享。

        【讨论】:

          【解决方案5】:

          请注意: - 服务器配置指南 启用网络 COM+ 访问 (Windows Server 2003) 开始 ==> 控制面板 ==> 添加或删除程序 ==> 添加/删除 Windows 组件,选择应用程序服务器,然后单击详细信息。单击启用网络 COM+ 访问,然后单击确定。单击下一步,然后单击完成。
          - 如果两台服务器之间有防火墙,则在此范围端口上为输入/输出打开防火墙: 单击开始 ==> 控制面板 ==> 管理工具 ==> 组件服务。展开组件服务,展开计算机,右键单击我的电脑并选择属性。 在我的电脑属性窗口中,单击选项卡默认协议,单击面向连接的 TCP/IP 并选择属性。在新窗口中,单击添加并键入新的 DTC 端口范围。 单击确定以应用这些更改。 必须重新启动服务器才能使新更改生效

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-24
            • 1970-01-01
            • 2012-04-25
            • 1970-01-01
            • 2021-01-01
            • 1970-01-01
            相关资源
            最近更新 更多