Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server ADO.NET SQLServer:如何防止关闭的连接持有S-DB锁?_Sql Server_Ado.net_Tcp_Connection Pooling - Fatal编程技术网

Sql server ADO.NET SQLServer:如何防止关闭的连接持有S-DB锁?

Sql server ADO.NET SQLServer:如何防止关闭的连接持有S-DB锁?,sql-server,ado.net,tcp,connection-pooling,Sql Server,Ado.net,Tcp,Connection Pooling,我创建了一个SqlConnection对象,当然了。我需要一个关闭的连接来不锁定数据库对象。如何防止关闭的连接锁定 为不知道的人解释上述句子: 关闭ADO或ADO.NET连接时,实际上并不是切断与SQL Server的连接。ADO/ADO.NET基础结构保持连接,以防您再次使用它。这些连接一直在所谓的“连接池”中徘徊 几分钟不使用后,连接将实际关闭。虽然,不是真的。TCP/IP有它自己的方法来保持TCP连接打开几分钟(处于“关闭\u等待”状态)。如果您要求再次打开到同一IP:端口的TCP连接

我创建了一个SqlConnection对象,当然了。我需要一个关闭的连接来不锁定数据库对象。如何防止关闭的连接锁定


为不知道的人解释上述句子:

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

  • 几分钟不使用后,连接将实际关闭。虽然,不是真的。TCP/IP有它自己的方法来保持TCP连接打开几分钟(处于“关闭\u等待”状态)。如果您要求再次打开到同一IP:端口的TCP连接,则可以执行此操作。如果是这样,它可以使用已经打开的TCP连接

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

  • 共享数据库锁的简单意思是,“请不要在我在数据库中时删除此数据库。”

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


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

connection.Dispose()
将其更改为对全局辅助函数的调用:

Database.DisposeConnection(connection);
这会将数据库上下文更改为

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

    connection.Dispose();
}
它解决了我眼前的问题;关闭的连接没有锁定我的数据库

但现在我担心连接池会让大脑混乱——因为我在背后切换了数据库上下文


如果有人不知道或不这么想:

发件人:

关闭处置在功能上 相当于


阅读注释时,您希望还原它

好的,把它离线

恢复不是应用程序应该做的事情,所以DBA在恢复之前运行它

ALTER DATABASE foo SET OFFLINE WITH ROLLBACK IMMEDIATE
你试过了吗

从MSDN:

ClearPool清除连接池 这与 连接。如果需要其他连接 与正在使用的连接关联 在打电话时,他们是 适当标记并丢弃 (而不是返回到 当对其调用Close时

只需在每个连接上调用ClearPool,但如果这样做,您将失去池的好处

public class DataFactory
{
  public SqlConnection CreateConnection(string connString)
  {
    SqlConnection conn = new SqlConnection(connString);
    SqlClient.ClearPool(conn);
    return conn;
   }
}
或者,您可以使用连接字符串的pooling属性禁用所有池:

string connString = "Data Source=MYSERVER;Initial Catalog=myDb;Integrated Security=true;Pooling=false"

正如您所说,当您关闭或处置一个连接时,它会返回到池中,但实际上并没有关闭

然后需要在中执行什么操作来关闭池中的所有连接。这可以通过ClearAllPools命令完成

ClearAllPools重置(或清空)连接池。如果有 发生故障时正在使用的连接 调用时,它们会被适当地标记 并将被丢弃(而不是 在关闭时返回到池中) 他们被召唤

还有一个ClearPool命令,它只对单个连接执行相同的操作

希望这有帮助


Shiraz

您可以将数据库置于单用户模式以恢复它。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;
请参阅:和/或了解更多背景信息

编辑:单用户模式用于备份和恢复(在非快速版上,我经常使用它)。使用它将取消所有其他连接,并且无法创建新连接。我没有使用过各种“with”选项,例如“rollbackimmediate”,但它们的用法似乎很简单。

首先执行“USE TempDB;”。然后关上它

或者“使用master;”,如果你更喜欢的话


在正常的生产操作期间,这些数据库上的S-DB锁都不重要,因为您无法摆脱其中任何一个并继续运行服务器。

另外,请尝试使用“using”关键字,而不是手动调用Dispose()。只是好奇,为什么这是个问题?这是个问题,因为你不能对数据库中的用户进行恢复。@Ray Booysen:我不能这样做,因为我必须在关闭连接之前更改数据库上下文。在SQL Server中执行恢复之前,您可以将连接/用户踢出数据库……如果DBA是63岁的祖母,她想要回她的刺绣设计呢?除非你提出在她的孙子修好她的电脑后开车去她家取回她的设计。DBA是否使用应用程序来运行恢复?也许是企业经理?SSMS?如果数据库上有其他连接(如维护作业),osql?connection.close将不起作用。但我怀疑根据你的评论你有这些。坚持使用.netWon。除非是我写的,否则我不会在快速版上做任何维护工作。我没有。是的,我真的不想失去100%的时间连接池的好处,因为恢复可能会发生0.0001%的时间。那么,在恢复数据库时,最好的办法就是像其他人所说的那样,将其置于单用户模式。您完全停止了进程,因此所有连接都肯定已关闭。我还没有进行测试,但这是否会导致SQL Server关闭池中所有已关闭的连接?如果是这样的话,这将是一个非常好的解决方案。不过,我认为您需要使用单独的SQL登录来实现此连接,以便进行管理。否则,您的所有连接仍然满足单用户标准,并且不会关闭。单用户模式更准确地说是单连接