views:

1499

answers:

3

I am having problems with SQL Server dropping a connection after I have dropped and re-created a given database and the next time I try to execute a command against a new connection on that same database, I get:

A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)

Here is the TCP version (If I try connecting to another server)

A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

Here are the steps to repro the problem:

  1. Open a connection to a database and execute a sql command
  2. Drop the database
  3. Re-Create the database
  4. Open a new connection to the same database and attempt to run a command against it

Result: I receive an exception

Here is the Code:

using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=DBNAME;Integrated Security=True"))
{
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "UPDATE ...";
    cmd.ExecuteNonQuery();
}

string sql = "Alter Database DBNAME set single_user with rollback immediate drop database DBNAME";
var server = new Microsoft.SqlServer.Management.Smo.Server(".");
server.ConnectionContext.ExecuteNonQuery(sql);
server.ConnectionContext.Disconnect();

sql = File.ReadAllText("PathToDotSqlFile..."));
server = new Microsoft.SqlServer.Management.Smo.Server(".");
server.ConnectionContext.ExecuteNonQuery(sql);
server.ConnectionContext.Disconnect();

using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=WER_CONFIG;Integrated Security=True"))
{
 conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "UPDATE ...";
    cmd.ExecuteNonQuery();
}

The error occurs on the line 'cmd.ExecuteNonQuery()' at the very end. It appears that even though I am creating a new connection each time I connect, sql server is keeping track of something (or possibly the ADO.net code) where the next time I ask for a connection, it gives me one that is already used or has been closed on the server side. It doesn't realize it was closed by the server (presumably because of the database it is connected to being dropped) until you try to execute another command against it.

Note that if I don't do the first step of executing the initial query, and I just drop the database, re-create it, and execute a command, I do not receive this error. I think establishing that initial connection before the database is dropped is an important part of this error.

I have also tried using an external process to drop and recreate the database like so:

ProcessStartInfo info = new ProcessStartInfo("sqlcmd.exe", " -e -E -S . -Q \"Alter Database DBNAME set single_user with rollback immediate drop database DBNAME\"");
var p = Process.Start(info);
p.WaitForExit();

info = new ProcessStartInfo("sqlcmd.exe", " -i " + PathToDotSqlFile);
p = Process.Start(info);
p.WaitForExit();

And that did not help.

Is there a way to create a new SqlConnection and ensure it is clean and not from a pool? Any other suggestions on how to solve this problem?

UPDATE: Using SqlConnection.ClearPool() did solve the problem but I chose to just edit my connection string with pooling=false which also worked.

+2  A: 

Don't know about SQL2008, but this sounds like a connection pooling problem on the application side. In the old days, we added "OLEDB Services=-1" to the connection string to turn off connection pooling. There is probably a more elegant way to do this now.

edit: ADO.Net 2.0 seems to have added a ClearPool function to the SQLConnection object. (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool(VS.80).aspx) I am very interested to know if this works.

Bill
+5  A: 

ADO.NET automatically manages a connection pool. When you "close" a connection in your application, it is returned to the pool and kept alive, in case you request a connection with the same connection string. This could be the reason why your "new" connection is stale.

You could try to turn off this behaviour by adding pooling=false as parameter to your connection string.

Sven Künzler
A: 

please can someone to help me: Hi, im using visual studio 2008 profesional edition and sql server 2008 where i got my database and when i try to run my aplication after making the functions by code to connect to the database i got the next msg:

  1. the program can not continue due to an incompatible database. the current data base version is". the aplication version is '1'.

Please if someone can help me with this problem i got lots of weeks trying to find answer and nothing, ive already instaled CTP and nothing works out.

my sqlserver managent studio 2008 is well installed.

and im using the following code to connect to my database:

   Dim connectionString As String

   ' ----- Initialize.

   HoldTransaction = Nothing

   ' ----- Build the connection string.

   ' !!! WARNING: Hardcoded for now.

   connectionString = "Data Source=tz\SQLEXPRESS;" & _

      "Initial Catalog=Library;Integrated Security=true"

   ' ----- Attempt to open the database.

   Try

       LibraryDB = New SqlClient.SqlConnection(connectionString)

       LibraryDB.Open()

   Catch ex As Exception

       GeneralError("ConnectDatabase", ex)

       Return False

   End Try

   ' ----- Success.

(admin - removed "e-mail me here")

thank u, u all help to make us better and grow up our knowledge

Hello Luis, you have placed a question as an answer to a different question. If you are requesting help, please remove this entry and create a new question. (see at "Ask Question" button at the top right)
Nathan Koop
Seconded; I don't really want to delete this (at least until you've had chance to copy the text into a new question) - but this isn't the place to ask a new question. See the top of the page for how to launch a new question.
Marc Gravell