【发布时间】:2022-12-18 08:11:59
【问题描述】:
下面显示了一种测试方法,该方法负责在 Windows 服务器启动期间针对 DTC 支持相互测试不同的 SQL Server 实例数据库组合。
然而,我们希望每对数据库的测试在短时间内(~15 秒)失败或通过。假设除此之外它无论如何都会失败 99%。
问题是,即使为 2 个 EF 上下文的 CommandTimeout 和事务本身指定了短超时,代码仍会在下面显示的行中暂停 2 分钟。
用于测试 2 个数据库 db1、db2 的 DTC 兼容性的 C# 代码:
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;
}
}
下面发布的错误似乎与未设置的每个数据库的“ConnectionTimeout”属性无关(并且它连接到数据库,因为它在调试时连接标志为真)。是否有一些可以在某处指定的 DTC 连接超时?
COMException: MSDTC 事务管理器无法提取 由于通信来自源事务管理器的事务 问题。可能的原因是:存在防火墙,但没有 MSDTC进程有异常,两台机器都找不到 彼此通过他们的 NetBIOS 名称,或对网络的支持 未为两个事务管理器之一启用事务。 (HRESULT 异常:0x8004D02B)
这篇文章的重点是解决超时错误,而不是 DTC 错误,因为代码的目的是测试 DTC,而失败是一个有效的结果,而这些 DTC 问题在另一天有自己的无数故障排除步骤。
【问题讨论】:
-
如果您注释掉 using(TransactionScope ... 它有效吗?如果您更改订单但保留它怎么办?它在第二个上仍然失败吗?如果是这样,我怀疑 DTC 问题可能会阻止第二个 EF为 SaveChanges 操作创建事务的上下文。
标签: c# sql-server distributed-transactions msdtc