jjzjj

sql-server - ADO.NET SQLServer : How to prevent closed connection from holding S-DB lock?

coder 2023-09-17 原文

Dispose一个 SqlConnection 对象,但当然是 it isn't really closed .我需要关闭连接才能不锁定数据库对象。如何防止关闭的连接持有锁?


上面这句话给不懂的解释一下:

  • 当您关闭 ADO 或 ADO.NET 连接时,实际上并没有切断与 SQL Server 的连接。 ADO/ADO.NET 基础结构保持连接,以防您再次使用它。这些连接在所谓的“连接池”中一直存在。

  • 几分钟不使用后,连接将实际上关闭。虽然,不是真的。 TCP/IP 有自己的方法来保持 TCP 连接打开几分钟(在“CLOSE_WAIT”状态)。这样做是为了防止您再次要求打开到同一 IP:Port 的 TCP 连接。如果是这样,它可以使用已经打开的 TCP 连接。

  • 使用连接池和 SQL Server,仍会建立与 SQL Server 的连接。每个连接都有一个它所在的数据库上下文。只要连接位于该数据库中:它就持有该数据库上的共享数据库 (S-DB) 锁。

  • 共享数据库锁只是意味着,“请不要删除我在其中的数据库。”

如何防止它在我的数据库上持有共享锁,同时保持连接池的好处?


我现在的临时解决方案是每次开发人员调用 Dispose 时:

connection.Dispose()

将其更改为对全局辅助函数的调用:

Database.DisposeConnection(connection);

将数据库上下文更改为ma​​ster:

public static void DisposeConnection(SqlConnection connection)
{
    //Stop holding a database lock - in my database at least
    ADOHelper.ExecuteNonQuery(connection, "USE master");

    connection.Dispose();
}

它解决了我眼前的问题;关闭的连接未锁定我的 数据库。

但现在我担心连接池会变得困惑 - 因为我在背后切换了数据库上下文。


万一有人不知道,或者不这么认为:

来自 the SDK :

Close and Dispose are functionally equivalent.

最佳答案

您可以将数据库置于单用户模式以便恢复它。 IIRC,像这样……

ALTER DATABASE TheDatabaseToRestore SET SINGLE_USER WITH  ROLLBACK IMMEDIATE;
RESTORE DATABASE TheDatabaseToRestore 
FROM DISK =N'Z:\Path\To\Backup\BackupFile';
ALTER DATABASE TheDatabaseToRestore SET MULTI_USER;

参见:Obtain Exclusive Access to Restore SQL Server和/或 Restore Database Backup using SQL了解更多背景信息。

编辑: 单用户模式用于备份和恢复(在非速成版上,我经常使用它)。使用它会踢出所有其他连接,并且无法建立新连接。我没有玩过各种“WITH”选项,例如“ROLLBACK IMMEDIATE”,但它们的用法似乎很简单。

关于sql-server - ADO.NET SQLServer : How to prevent closed connection from holding S-DB lock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/520716/

有关sql-server - ADO.NET SQLServer : How to prevent closed connection from holding S-DB lock?的更多相关文章

随机推荐