How to use TransactionScope in C#?

How to use TransactionScope in C#?

爱的故事 发布于 2021-11-24 字数 1516 浏览 850 回复 7 原文

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


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

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:

Here are the properties on the server:

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。



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


小帐篷 2022-06-07 7 楼

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.

-旧情别恋。 2022-06-07 6 楼

You need to enable network DTC access for both the database server and the server where the application runs on.

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.

笑叹一世浮沉 2022-06-07 5 楼

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.

You can fix this by starting the MSDTC service, upgrading to SQL Server 2005, or implement something like my codeproject solution:

I've never needed to do it, but you should also check Ocdecio's answer for configuring the network security settings for DTC, too.

生生不灭 2022-06-07 4 楼

You need to enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.

十雾 2022-06-07 3 楼

Depending on the backend you are using, TransactionScope often requires the Distributed Transaction Manager to be enabled. Some details are on this MSDN blog.

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.

逆流 2022-06-07 2 楼

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)

Reboot computer.

自此以后,行同陌路 2022-06-07 1 楼

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:
Security Configuration Screenshot

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
MSDTC network transactions will not be
able to work properly. MSDTC supports
(0) and
values. See
for more info on

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,
    // your code here