如何在 C# 中使用 TransactionScope?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/794364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use TransactionScope in C#?
提问by NotDan
I am trying to use TransactionScope
, but keep getting the exception below.
The app is running on a different machine than the database, if that matters. I am using SQL Server 2005.
我正在尝试使用TransactionScope
,但不断收到以下异常。
如果重要的话,该应用程序运行在与数据库不同的机器上。我正在使用 SQL Server 2005。
Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.
分布式事务管理器 (MSDTC) 的网络访问已被禁用。请使用组件服务管理工具在 MSDTC 的安全配置中为网络访问启用 DTC。
using (TransactionScope tsTransScope = new TransactionScope())
{
//Do stuff here
tsTransScope.Complete();
}
Edit
编辑
I made some changes based on the feedback. Now I'm getting this error:
我根据反馈做了一些更改。现在我收到此错误:
"Error HRESULT E_FAIL has been returned from a call to a COM component."
"Communication with the underlying transaction manager has failed."
“错误 HRESULT E_FAIL 已从对 COM 组件的调用返回。”
“与底层事务管理器的通信失败。”
SolutionI think the accepted answer fixed the initial issue I was getting. The 2nd error seems to be specific to Entity Framework. I'll post another question for it.
解决方案我认为接受的答案解决了我遇到的最初问题。第二个错误似乎特定于实体框架。我会为此发布另一个问题。
Here are the properties on the client:
Client http://www.portnine.com/data/images/Misc/client.jpg
以下是客户端的属性:
客户端 http://www.portnine.com/data/images/Misc/client.jpg
Here are the properties on the server:
Server http://www.portnine.com/data/images/Misc/server.jpg
以下是服务器上的属性:
服务器 http://www.portnine.com/data/images/Misc/server.jpg
采纳答案by ahsteele
You need to enable network DTC access as described in this Microsoft TechNet Article. This change may have to be made on both the database and application servers. Often times DTC is already turned on a database server so I'd look at the application server first.
您需要按照Microsoft TechNet 文章 中的说明启用网络 DTC 访问。可能必须在数据库和应用程序服务器上进行此更改。通常,DTC 已在数据库服务器上打开,因此我会先查看应用程序服务器。
Here is a screen shot of what we use except for the "Allow Remote Administration" option:
这是我们使用的屏幕截图,除了“允许远程管理”选项:
I have not run into the HRESULT E_Fail issue you are now having but this article on XP SP2 and transactionshad this interesting suggestion:
我还没有遇到您现在遇到的 HRESULT E_Fail 问题,但是这篇关于XP SP2 和事务的文章有这个有趣的建议:
Another configuration setting that you need to be aware (although I consider it to be an uncommon scenario) is RestrictRemoteClients registry key. If the value of this key is set to 2 (RPC_RESTRICT_REMOTE_CLIENT_HIGH) then MSDTC network transactions will not be able to work properly. MSDTC supports only RPC_RESTRICT_REMOTE_CLIENT_NONE (0) and RPC_RESTRICT_REMOTE_CLIENT_DEFAULT (1) values. See http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx#XSLTsection128121120120for more info on RestrictRemoteClients.
您需要注意的另一个配置设置(尽管我认为这是一种不常见的情况)是 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。
Finally, while not specific to your issue a very important thing to note about using the TransactionScope
class is that its default setting is to utilize a Transaction Isolation Level of Serializable. Serializable is the most restrictive of the isolation levels and frankly its surprising that it was chosen as the default. If you do not need this level of locking I would highly recommend setting the isolation level to a less restrictive option (ReadCommitted) when instantiating a TransactionScope
:
最后,虽然不是特定于您的问题,但使用TransactionScope
该类时要注意的一个非常重要的事情是它的默认设置是使用Serializable的事务隔离级别。Serializable 是限制性最强的隔离级别,坦率地说,它被选为默认级别令人惊讶。如果您不需要这种级别的锁定,我强烈建议在实例化 a 时将隔离级别设置为限制较少的选项(ReadCommitted)TransactionScope
:
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
}
回答by Neil Barnwell
If you are using SQL Server 2000, System.Transactions.TransactionScope
will cause all transactions to be promoted to Distributed Transactions, requiring MS Distributed Transaction Coordinator to be running.
如果您使用的是 SQL Server 2000,System.Transactions.TransactionScope
将导致所有事务都被提升为分布式事务,需要 MS 分布式事务协调器才能运行。
You can fix this by starting the MSDTC service, upgrading to SQL Server 2005, or implement something like my codeproject solution: http://www.codeproject.com/KB/database/typed_dataset_transaction.aspx
您可以通过启动 MSDTC 服务、升级到 SQL Server 2005 或实施类似我的 codeproject 解决方案来解决此问题:http: //www.codeproject.com/KB/database/typed_dataset_transaction.aspx
I've never needed to do it, but you should also check Ocdecio's answer for configuring the network security settings for DTC, too.
我从来不需要这样做,但您也应该检查 Ocdecio 的答案,以配置 DTC 的网络安全设置。
回答by Otávio Décio
Control Panel - Administrative Tools - Component Services - My Computer properties - MSDTC tab - Security Configuration tab - Network DTC Access (checked) / Allow Remote Clients (checked) / Allow Inbound (checked) / Allow Outbound (checked) / Enable TIP Transactions (checked)
控制面板 - 管理工具 - 组件服务 - 我的电脑属性 - MSDTC 选项卡 - 安全配置选项卡 - 网络 DTC 访问(选中)/允许远程客户端(选中)/允许入站(选中)/允许出站(选中)/启用 TIP 事务(勾选)
Reboot computer.
重启电脑。
回答by Reed Copsey
Depending on the backend you are using, TransactionScope often requires the Distributed Transaction Manager to be enabled. Some details are on this MSDN blog.
根据您使用的后端,TransactionScope 通常需要启用分布式事务管理器。此 MSDN 博客上提供了一些详细信息。
Also, if you use multiple resources, DTC may be required. Enabling DTC may be required in your situation, or making sure you're using SQL Server 2005 and sticking to what would be doable in lightweight transactions.
此外,如果您使用多个资源,则可能需要 DTC。在您的情况下可能需要启用 DTC,或者确保您使用的是 SQL Server 2005 并坚持在轻量级事务中可行。
回答by Mia Clarke
You need to enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.
您需要使用组件服务管理工具在 MSDTC 的安全配置中为网络访问启用 DTC。
回答by Dries Van Hansewijck
You need to enable network DTC access for both the database server and the server where the application runs on.
您需要为数据库服务器和应用程序运行所在的服务器启用网络 DTC 访问。
You will also need to verify that connections will not be blocked by a firewall. Since a connection will be initiated from the database server to the application machine, it is equally important to add MSDTC to the list of firewall exceptions on the application machine.
您还需要验证连接不会被防火墙阻止。由于将启动从数据库服务器到应用程序计算机的连接,因此将 MSDTC 添加到应用程序计算机上的防火墙例外列表中同样重要。
回答by Joseph
I had the same problem running integration tests.
我在运行集成测试时遇到了同样的问题。
I posted a question about this here
我在这里发布了一个关于这个的问题
but eventually I found a way around it. Although, I wouldn't recommend doing that for production code. I was doing it within the context of testing.
但最终我找到了解决方法。虽然,我不建议为生产代码这样做。我是在测试的背景下做的。