问题
I'm using TransactionScope to make a method that contains multiple sql statements transactional. Now i need to call a second method that also uses the same connection and i receive following exception at connection.Open()
:
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.
So this is the pseudo-code:
public static void Method1()
{
using (TransactionScope scope = new TransactionScope())
{
bool success = true; // will be set to false in an omitted catch
using (var connection = new SqlConnection(ConnectionString1))
{
// ...
if(somethingHappened)
Method2();
}
if(success)
scope.Complete();
}
}
public static void Method2()
{
using (var connection = new SqlConnection(ConnectionString1))
{
connection.Open(); // BOOOM!
// ...
}
}
How to avoid this exception without repeating the code from Method2
in Method1
?
回答1:
If more then one connection are open under same TransactionScope
it will be automatically escalated to the DTC.
You need to close first connection before calling Method2
.
public static void Method1()
{
using (TransactionScope scope = new TransactionScope())
{
bool success = true; // will be set to false in an omitted catch
bool isSomethingHappened
using (var connection = new SqlConnection(ConnectionString1))
{
isSomethingHappened = // Execute query 1
}
if(somethingHappened)
Method2();
if(success)
scope.Complete();
}
}
回答2:
Nested connections under the same transaction scope will promote to a distributed transaction.
From SQL server 2008 and above multiple (not nesting) connections under the same transaction scope will not promote to a distributed transaciton.
see this question for more information
回答3:
I don't know the precise answer, but I would make the connection a member, and keep track if it's open.
Then in Method1 and Method2 I would get the connection via some GetConnection() which would open the connection on first use.
After reading the comments I would suggest a private DoMethod2 which takes in a connection object.
来源:https://stackoverflow.com/questions/40719155/transactionscope-and-method-call-that-uses-the-same-connection