简体   繁体   English

C#-SQL连接无法关闭

[英]C# - SQL Connection won't close

I'm making a C#program that interacts with some SQL Server databases. 我正在制作一个与某些SQL Server数据库进行交互的C#程序。 The problem is if I connect to a database (dbA) and then close this connection and open another one to another database (dbB) and then do a Restore of dbA, the SqlException triggers saying that database (dbA) is in use. 问题是,如果我连接到数据库(dbA),然后关闭此连接,然后再打开另一个数据库到另一个数据库(dbB),然后执行dbA还原,则SqlException触发说数据库(dbA)正在使用。 However if I execute the program and connect only to dbB, I can restore the other databases without problem, is like the first connection is kept stored. 但是,如果我执行程序并仅连接到dbB,则可以毫无问题地还原其他数据库,就像保持第一个连接一样。 Anyway here is the code where the connection should open and close: 无论如何,以下是连接应该打开和关闭的代码:

private bool CheckConnection()
    {
        bool res = false;
        string conString = string.Empty;
        if (!String.IsNullOrEmpty(serverBox.Text) && !String.IsNullOrEmpty(dbBox.Text))
        {
            conString = ConcatConString(dbBox.Text);
            using (SqlConnection conn = new SqlConnection(conString))
            {
                conn.Open();
                if (conn.State == ConnectionState.Open)
                {
                    res = true;
                }
            }
        }        
        return res;
    }

ADO.NET uses connection pooling to reuse expensive connection objects. ADO.NET使用连接池来重用昂贵的连接对象。 When you close a connection, any existing transactions are rolled back, its server-side state is reset and it's placed in the connection pool awating for the next Open command. 关闭连接时,所有现有事务都会回滚,其服务器端状态将重置,并将其放置在连接池中,等待下一个“ Open命令。

To the server though, that still counts as a server connection when you try to take such drastic actions as shutting down the server, restoring the database etc. That means that you have to take explicit action and tell the server that it's OK to proceed. 但是,对于服务器而言,当您尝试执行诸如关闭服务器,还原数据库等剧烈动作时,该连接仍视为服务器连接。这意味着您必须采取显式操作并告诉服务器可以继续进行。

In this case, you need to set the database to SINGLE USER mode, perform the restore operation then bring it back to MULTI USER mode, eg: 在这种情况下,您需要将数据库设置为“单用户”模式,执行还原操作,然后将其恢复为“多用户”模式,例如:

ALTER DATABASE [MyDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE [MyDB] ...
ALTER DATABASE [MyDB] SET MULTI_USER

That's what SSMS does by the way, when you check the "Close Existing Connections to Database" option when restoring 这就是SSMS所做的,当您在还原时选中“关闭数据库的现有连接”选项时

You can also use WITH ROLLBACK AFTER xx SECONDS if you want give some time to existing connections to finish. 如果您想给现有连接一些时间来完成,也可以使用WITH ROLLBACK AFTER xx SECONDS In this case though, you are going to overwrite the database. 但是,在这种情况下,您将覆盖数据库。

Closing a connection does not close it at the database, it just returns the connection to the pool maintained by ADO.Net. 关闭连接不会在数据库处关闭它,它只是将连接返回到ADO.Net维护的池。 Normally I would never suggest this but it seems you may have a legitimate case for disabling connection pooling. 通常,我永远不会建议这样做,但是似乎您可能有禁用连接池的合理理由。

In the connection string set the Pooling attribute to no or false and the connection should actually close on the server. 在连接字符串中,将Pooling属性设置为nofalse ,连接实际上应该在服务器上关闭。

You can observe how it works by running sp_who2 in SSMS with connection pooling enabled or disabled in the following code: 您可以通过在以下代码中启用或禁用连接池的SSMS中运行sp_who2来观察其工作方式:

class Program
{
    static void Main(string[] args)
    {
        SqlConnectionStringBuilder bldr = new SqlConnectionStringBuilder();
        bldr.IntegratedSecurity = true;
        bldr.InitialCatalog = "YourDB";
        bldr.DataSource = "(localdb)\\YourServer";
        bldr.Pooling = false;  //Comment and uncomment this and run sp_who2

        using (SqlConnection con = new SqlConnection(bldr.ConnectionString))
        {
            con.Open();
        }
    }
}

Update 更新资料

Don't do this unless your program is the only thing connecting. 除非您的程序是唯一的连接,否则不要这样做。 I got the impression that the program was specifically for restoring databases. 我觉得该程序专门用于还原数据库。 If you have other clients on the databases then this will tank performance. 如果数据库上还有其他客户端,则会降低性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM