A test method that is responsible for testing different SQL Server instances database combinations against each other for DTC support during startup of a windows server is shown below.
However we want the testing of each pair of databases to fail or pass within a short time frame of (~15s). Assume that beyond that it will fail 99% anyway.
The problem is, even though a short timeout is specified for the CommandTimeout's of 2 EF contexts and the transaction itself, the code still pauses for 2 minutes on the line shown below.
C# code to test DTC compatibility for 2 databases db1, db2:
bool TestDbPair(SomeDb db1, SomeDb db2)
{
try
{
int timeoutSeconds = 15;
TransactionOptions xactOpts = new TransactionOptions();
xactOpts.IsolationLevel = IsolationLevel.ReadCommitted;
xactOpts.Timeout = new TimeSpan(0, 0, timeoutSeconds + 3); // +fudge since it should wraps CommandTimeout below
using (TransactionScope dbTransaction = new TransactionScope(TransactionScopeOption.Required, xactOpts))
using (CommonContext cmnCtx1 = db1.NewCommonContext())
using (CommonContext cmnCtx2 = db2.NewCommonContext())
{
cmnCtx1.Database.CommandTimeout = timeoutSeconds;
cmnCtx2.Database.CommandTimeout = timeoutSeconds;
Environment env = new Environment
{
PropertyName = _propertyName,
StringValue = "Test",
CreatedBy = "ServerTest",
CreatedUtc = DateTime.UtcNow,
ModifiedBy = "ServerTest",
ModifiedUtc = DateTime.UtcNow,
Comments = "test",
};
cmnCtx1.Environment.Add(env);
cmnCtx2.Environment.Add(env);
cmnCtx1.SaveChanges();
cmnCtx2.SaveChanges(); // <<<--- hangs here for ~2 minutes
dbTransaction.Complete();
return true;
}
}
catch (Exception)
{
return false;
}
}
The error is posted below doesn't seem related to the "ConnectionTimeout" property of each database which was not set (and it connected to databases since it Connected flag is true while debugging). Is there some connect timeout for the DTC that can be specified somewhere?
COMException: The MSDTC transaction manager was unable to pull the transaction from the source transaction manager due to communication problems. Possible causes are: a firewall is present and it doesn't have an exception for the MSDTC process, the two machines cannot find each other by their NetBIOS names, or the support for network transactions is not enabled for one of the two transaction managers. (Exception from HRESULT: 0x8004D02B)
The focus of this post is to solve the timeout error not the DTC error since the purpose of the code is to test DTC with failure being a valid result and these DTC issues have a myriad of their own troubleshooting steps for another day.
The transaction timeout you are setting tells the transaction manager that the transaction itself should not take longer than the set timeout. The Transaction timeout only comes into play when both databases are reporting their outcome to the transaction manager. The exception you are getting shows that the transaction manager is not able to talk to one of the databases, which is a totally different problem.
That is more like a network problem where other timeouts are playing.