针对 Sql Server 2000 的 TransactionScope 错误 - 合作伙伴事务管理器已禁用其对远程/网络事务的支持

发布于 2024-07-09 07:27:22 字数 1218 浏览 10 评论 0原文

我正在尝试为我的 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 和我的客户端计算机上运行。

I am trying to set up a simple transaction for my Linq-to-Sql actions against my Sql 2000 database. Using TransactionScope it looks like this:

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;
    }
}

However, i keep getting the following error:

The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)

But, if I set up the transaction using a traditional transaction, it works fine. So this works fine:

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;
}

I'm wondering if the TransactionScope is doing something different under the covers than my second implementation. If not, what am I losing by not using TransactionScope? Also, any guidance on what is causing the error would be good too. I've confirmed that MSDTC is running in both sql server and on my client machine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

初与友歌 2024-07-16 07:27:22

请看这里:

使用 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

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

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

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

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

Take a look here:

Fast transactions with System.Transactions and Microsoft SQL Server 2000
http://blogs.msdn.com/florinlazar/archive/2005/09/29/475546.aspx

And here:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=230390&SiteID=1

First verify the "Distribute Transaction Coordinator" Service is
running on both database server computer and client computers
1. Go to "Administrative Tools > Services"
2. Turn on the "Distribute Transaction Coordinator" Service if it is not running

If it is running and client application is not on the same computer as
the database server, on the computer running database server
1. Go to "Administrative Tools > Component Services"
2. On the left navigation tree, go to "Component Services > Computers > My Computer" (you may need to double click and wait as some nodes
need time to expand)
3. Right click on "My Computer", select "Properties"
4. Select "MSDTC" tab
5. Click "Security Configuration"
6. Make sure you check "Network DTC Access", "Allow Remote Client",
"Allow Inbound/Outbound", "Enable TIP" (Some option may not be
necessary, have a try to get your configuration)
7. The service will restart
8. BUT YOU MAY NEED TO REBOOT YOUR SERVER IF IT STILL DOESN'T WORK
(This is the thing drove me crazy before)

On your client computer use the same above procedure to open the
"Security Configuration" setting, make sure you check "Network DTC
Access", "Allow Inbound/Outbound" option, restart service and computer
if necessary.

On you SQL server service manager, click "Service" dropdown, select
"Distribute Transaction Coordinator", it should be also running on
your server computer.

别再吹冷风 2024-07-16 07:27:22

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;
    }
}

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

但弗洛林·拉扎尔表示,这是故意的。

并且您也不得关闭
连接,因为连接
应保持开放状态直至交易完成
已完成,这发生在
“using”语句结束。 适配器
将取得连接的所有权
生命周期并在完成后关闭它
有了它。

The DatabaseTransactionAdapter implementation in the Florin Lazar post that Keith Sirmons pointed me to seems to do the trick. Here's my code that calls it:

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;
    }
}

The only thing that makes me uneasy is that I'm not explicitly closing the connection even though it's not declared within a 'using' statement.

But according to Florin Lazar, that's on purpose.

And you also must not close the
connection, because the connection
should stay open until the transaction
is completed, which happens after the
“using” statement ends. The adapter
will take ownership of the connection
lifetime and close it when it is done
with it.

并安 2024-07-16 07:27:22

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

首先验证“Distribute Transaction Coordinator”服务是否
在数据库服务器计算机和客户端计算机上运行

  1. 转至“管理工具 > 服务”
  2. 如果“分布式事务协调器”服务未运行,请将其打开

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

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

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

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

The steps to enable this on Windows 2008 or later are:

First verify the "Distribute Transaction Coordinator" Service is
running on both database server computer and client computers

  1. Go to "Administrative Tools > Services"
  2. Turn on the "Distribute Transaction Coordinator" Service if it is not running

If it is running and client application is not on the same computer as
the database server, on the computer running database server

  1. Go to "Administrative Tools > Component Services"
  2. On the left navigation tree, go to "Component Services > Computers > My Computer > Distributed Transaction Coordinator" (you may need to double click and wait as some nodes need time to expand)
  3. Right click on "Local DTC", select "Properties"
  4. Select "Security" tab
  5. Make sure you check "Network DTC Access", "Allow Remote Client", "Allow Inbound/Outbound"
  6. The service will restart
  7. BUT YOU MAY NEED TO REBOOT YOUR SERVER IF IT STILL DOESN'T WORK (This is the thing drove me crazy before)

On your client computer use
the same above procedure to open the "Security Configuration" setting,
make sure you check "Network DTC Access", "Allow Inbound/Outbound"
option, restart service and computer if necessary.

On your SQL server
service manager, click "Service" dropdown, select "Distribute
Transaction Coordinator", it should be also running on your server
computer.

满地尘埃落定 2024-07-16 07:27:22

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

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

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

转到 SQL Client 确实解决了我的问题,这也证实了这是 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 一定是首选,但我觉得如果其他有类似问题的人通过谷歌找到这里,这至少值得分享。

I post the below solution here because after some searching this is where I landed, so other may too. I was trying to use EF 6 to call a stored procedure, but had a similar error because the stored procedure had a linked server being utilized.

The operation could not be performed because OLE DB provider _ for linked server _ was unable to begin a distributed transaction

The partner transaction manager has disabled its support for remote/network transactions

Jumping over to SQL Client did fix my issue, which also confirmed for me that it was an EF thing.

EF model generated method based attempt:

db.SomeStoredProcedure();

ExecuteSqlCommand based attempt:

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

With:

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();

That code can be shortened, but I think that version is slightly more convenient for debugging and stepping through.

I don't believe that Sql Client is necessarily a preferred choice, but I felt this was at least worth sharing if anyone else having similar problems gets landed here by google.

余罪 2024-07-16 07:27:22

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

more notice that:
- Server Configuration Guide
Enable network COM+ access (Windows Server 2003)
Start ==> Control Panel ==> Add or Remove Programs ==>Add/Remove Windows Components, Select Application Server, and then click Details. Click Enable network COM+ access, and then click OK. Click Next, and then click Finish.
- If between 2 server have firewall, open firewall for both in/out on this range port:
Click Start ==> Control Panels ==> Administrative Tools ==> Component Services. Expand Component service, expand Computers, Right click on My Computer and choose Properties.
In the My Computer Properties window, click on tab Default Protocol, click on connection-oriented TCP/IP and choose properties. in the new window, click add and type new DTC ports range.
Click on OK to apply these change.
Server must be restart for new change take effect

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文