在分布式事务中手动登记后,使用 enlist=false 的连接不会关闭
我有一个使用 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)。 (请注意,如果您想在不创建表的情况下测试它,您可以完全删除该命令。)
我错过了什么或做错了什么?
I have a distributed transaction context using ServiceDomain
. Inside it, I open an SQL connection with connection string specifying Enlist=false
, so that it is not automatically enlisted in the transaction. Then, if I manually enlist the connection in the distributed transaction using EnlistDistributedTransaction
, the connection does not get closed, which can end in an InvalidOperationException
with:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Try the following:
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();
}
This gets stuck (and dies after a timeout) at 200 connections, as all 100 enlisted connections obviously do not get closed (and the default connection pool size is 100). (Note that you can remove the command altogether if you want to test it without creating the table.)
What am I missing or doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试在查询执行结束时设置
conn.EnlistDistributedTransaction(null);
。Try setting
conn.EnlistDistributedTransaction(null);
at the end of query execution.