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

你离开我真会死。 提交于 2019-12-03 11:57:32

You can place the database in single user mode in order to restore it. IIRC, something like this...

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;

see: Obtain Exclusive Access to Restore SQL Server and/or Restore Database Backup using SQL for some more background.

Edit: Single user mode is intended for backups and restores (which, on the non-express edition, is what I use it for regularly). Using it kicks out all other connections, and new connections cannot be made. I haven't played with the various "WITH" options such as with "ROLLBACK IMMEDIATE", but their usage seems straightforward.

Have you tried SqlClient.ClearPool?

From MSDN:

ClearPool clears the connection pool that is associated with the connection. If additional connections associated with connection are in use at the time of the call, they are marked appropriately and are discarded (instead of being returned to the pool) when Close is called on them.

Just call ClearPool on every connection, but you lose the pooling benefits if you do this.

public class DataFactory
{
  public SqlConnection CreateConnection(string connString)
  {
    SqlConnection conn = new SqlConnection(connString);
    SqlClient.ClearPool(conn);
    return conn;
   }
}

Alternatively, you can disable pooling all together using the Pooling property of the connection string:

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

As you say when you Close or Dispose a connection it goes back into the pool but is not really closed.

What you then need to do in to close all connections in the pool. This can be done with a ClearAllPools command.

ClearAllPools resets (or empties) the connection pool. If there are connections in use at the time of the call, they are marked appropriately and will be discarded (instead of being returned to the pool) when Close is called on them.

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearallpools(VS.80).aspx

There is also a ClearPool command that does the same thing but for a single connection.

Hope this helps

Shiraz

Execute "USE TempDB;" first. Then close it.

Or "USE master;", if that's more to your liking.

S-DB locks on either of those databases shouldn't matter during normal production operation, as you cannot get rid of either one and continue running the Server anyway.

Reading the comment, you want to restore it.

OK, take it off-line.

Restore is not something that an app should be doing, so the DBA runs this before the RESTORE.

ALTER DATABASE foo SET OFFLINE WITH ROLLBACK IMMEDIATE
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!