seanprice

Killing ProcessIDs using SMO

"Exclusive Access could not be obtained because the database is in use"

The above line should look familiar to anyone who has done a Database Restore and is easily solved if you are using Management
Studio or Query Analyzer. My personal favorite is to just kick the DB into single user mode, which drops any errant connections.

use master
go

alter database <dbname> set single_user with rollback immediate
alter database <dbname> set multi_user

I know some who prefer to explicitly drop the connections through the Activity Monitor and others who use a cursor based solution to cycle through the connections. To each his own...

I ran into this problem recently while using SMO to do a Database Restore. At my company, we have a process where we get an XML
file containing records dropped into a specific FTP folder from a 3rd party. I wrote a listener program that takes that XML file and
imports it into a staging DB. As part of the process, it does a backup of the DB and in the event of an import error, the DB gets
rolled back. This worked fine until I noted some errors in my log with the above "Exclusive Access" message, which led me on a
hunt to find out how to kill the processes using SMO.

After a bit of thinking (OK, and guessing...), I found 2 methods on the Server class itself. One takes a database name as an argument and kills all the running processes for that database.
The other one kills a single process by taking a processID as an argument. 

public void KillAllProcesses(string databaseName);
public void KillProcess(int processId); 

My modified code is below, with the "KillAllProcesses" line added. Hopefully this will be of help to someone else with the same problem. 

internal void RestoreDatabase(string backupFileName, string databaseName)
 {   
    Restore restore = new Restore();
    restore.Database =
databaseName;

    restore.Devices.AddDevice(backupFileName, DeviceType.File);
    restore.ReplaceDatabase = true;
    _server.KillAllProcesses(
databaseName);
    restore.Wait();
    restore.SqlRestore(_server);
 
}


 

Posted: Jul 11 2007, 04:09 PM by seanprice | with 3 comment(s)
Filed under:

Comments

bocajr said:

The first bit of code that you wrote to set the DB into single user mode - how do you reset it

this is prob sounds like a silly question, but i'm just learning sql

# July 24, 2007 8:01 PM

seanprice said:

bocarj,

The second piece of T-SQL code will set the DB back into Multi-user mode.

use master

go

alter database <dbname> set multi_user

# July 24, 2007 8:19 PM

SergioTarrillo's RichWeblog said:

Si están usando SQL Server Management Studio para restaurar un backup de una base de datos, puede que

# July 29, 2007 4:14 AM