手动征用分布式事务后,使用enlist = false的连接不会关闭 [英] Connection using enlist=false does not close after being manually enlisted in distributed transaction

查看:170
本文介绍了手动征用分布式事务后,使用enlist = false的连接不会关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 ServiceDomain 的分布式事务上下文。在其中,我打开一个带有连接字符串的SQL连接,该连接字符串指定 Enlist = false ,这样它就不会自动登记在事务中。然后,如果我使用 EnlistDistributedTransaction 手动将连接注册到分布式事务中,则该连接不会关闭,可能会以 InvalidOperationException ,其中:

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
{
    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)。 (请注意,如果要在不创建表的情况下对其进行测试,则可以完全删除该命令。)

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?

推荐答案

在查询执行结束时尝试设置 conn.EnlistDistributedTransaction(null);

Try setting conn.EnlistDistributedTransaction(null); at the end of query execution.

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);
}

这篇关于手动征用分布式事务后,使用enlist = false的连接不会关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆