如何在C#中使用TransactionScope? [英] How to use TransactionScope in C#?

查看:122
本文介绍了如何在C#中使用TransactionScope?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 TransactionScope ,但始终在下面出现异常。

该应用程序在与数据库不同的计算机上运行,​​如果这很重要。我正在使用SQL Server 2005。


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




  using(TransactionScope tsTransScope = new TransactionScope())
{
//在此处进行操作
tsTransScope.Complete();
}

编辑



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


错误HRESULT E_FAIL已从对COM组件的调用返回。

与基础事务管理器的通信失败。


解决方案
我认为接受的答案解决了我遇到的最初问题。第二个错误似乎特定于实体框架。我会再提出一个问题。



以下是客户端上的属性:

有一个有趣的建议:



需要的另一种配置设置要知道(尽管我认为
是不常见的情况)是
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
了解有关
RestrictRemoteClients的更多信息。


最后,虽然不是特定于您的问题,但是关于使用 TransactionScope 类的一件非常重要的事情要注意,它的默认设置是使用可序列化的交易隔离级别。可序列化是隔离级别中最严格的限制,坦率地说,令人惊讶的是它被选择为默认级别。如果不需要此级别的锁定,我强烈建议在实例化 TransactionScope

$ b $时将隔离级别设置为限制性较小的选项(ReadCommitted)。 b

  var scopeOptions = new TransactionOptions(); 
scopeOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
scopeOptions.Timeout = TimeSpan.MaxValue;

使用(var scope = new TransactionScope(TransactionScopeOption.Required,
scopeOptions))
{
//您的代码在这里
}


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.

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.

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."

Solution I 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

Here are the properties on the server:
Server http://www.portnine.com/data/images/Misc/server.jpg

解决方案

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.

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 transactions had this interesting suggestion:

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#XSLTsection128121120120 for more info on RestrictRemoteClients.

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:

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
}

这篇关于如何在C#中使用TransactionScope?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆