我有一个使用 ServiceDomain
的分布式事务上下文。在其中,我打开一个 SQL 连接,连接字符串指定 Enlist=false
,以便它不会自动加入事务。然后,如果我使用 EnlistDistributedTransaction
在分布式事务中手动登记连接,则连接不会关闭,它可以以 InvalidOperationException
结尾:
请尝试以下操作:
try
{
var configuration = new ServiceConfig
{
Transaction = TransactionOption.Required,
TransactionTimeout = 1000
};
ServiceDomain.Enter(configuration);
for (var i = 0; i < 500; ++i)
{
Console.WriteLine(i);
using (var conn = new SqlConnection("Data Source=localhost;Initial Catalog=dotest;Integrated Security=SSPI;Enlist=False;"))
{
conn.Open();
if (i % 2 == 0) conn.EnlistDistributedTransaction((ITransaction) ContextUtil.Transaction);
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO [Test]([ID]) VALUES(@num)";
cmd.Parameters.AddWithValue("@num", i);
cmd.ExecuteNonQuery();
}
}
}
ContextUtil.SetAbort();
}
finally
{
ServiceDomain.Leave();
}
这在 200 个连接时卡住(并在超时后死亡),因为所有 100 个登记的连接显然没有关闭(并且默认连接池大小为 100)。 (请注意,如果您想在不创建表的情况下对其进行测试,则可以完全删除该命令。)
我错过了什么或做错了什么?
最佳答案
尝试在查询执行结束时设置 conn.EnlistDistributedTransaction(null);
。
using (var conn = new SqlConnection("Data Source=localhost;Initial Catalog=dotest;Integrated Security=SSPI;Enlist=False;"))
{
conn.Open();
if (i % 2 == 0) conn.EnlistDistributedTransaction((ITransaction) ContextUtil.Transaction);
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO [Test]([ID]) VALUES(@num)";
cmd.Parameters.AddWithValue("@num", i);
cmd.ExecuteNonQuery();
}
conn.EnlistDistributedTransaction(null);
}
关于.net - 在分布式事务中手动登记后,使用 enlist=false 的连接不会关闭,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5633341/