Question

When I'm creating temp tables I get an error message telling me that the temp table already exists. The temp table is unique to the session so it seems my connection isn't closing properly and I think it may have something to do with a return statement I have in my using statement.

I have the following code:

using (IDbConnection connection = dbConnectionHandler.CreateConnection())
{
   connection.Open();
   CreateATempTable();
   PopulateTempTable();
   DataSet ds = CallStoredProcThatUsesTempTable();
   return ds;
}

I use this sort of code in several places to create a temp table with the same name.

Unfortunately, I'm getting the following error: There is already an object named '#MyTempTable' in the database.

Now, I know that the temp table is unique to the session and so once the session is closed it should disappear.

There are three things that I believe might cause this...

  1. I need to call connection.Close()
  2. I need to place the return statement outside my using statement
  3. I need to drop the temp table I created prior to returning

Does anyone know which one it is? or if its something I haven't thought of?

Was it helpful?

Solution

I'm guessing here but check your database connection pooling settings. Try turning pooling off and see if it helps.

Usually, when you close/dispose connection on the .NET libraries level, real database server connection is not closed. It is just returned to connection pool inside data provider and will be reused when program asks for another connection with the same parameters and credentials. I don't think database session is reset in any way before being returned to the pool, except for open transactions and maybe some basic parameters. More expensive objects, like temporary tables, are left alone.

You can turn pooling off (very inefficient). Or you can check temporary table existence before trying to create it and delete its content if it exists. Or you can drop temporary table before closing connection.

OTHER TIPS

I am pretty sure that connection.Dispose() (and thus connection.Close() as well) will be called.

You can verify that easily enough by doing 1) and 2) and checking that the problem still exists. The solution is probably 3) and the explanation would be Connection pooling.

Unless a power cycle occurs or some other seriously bizarre corner case dispose WILL be called.

If you want proof wrap the object and put a breakpoint in.

A using block is translated into a try/catch/finally block under the hood. Yes it will dispose regardless of the return within the using block.

No, connection.Close will always be called because internally using puts it in a try/finally block.

You also may want to consider connection pooling. Try wrapping your code in a TransactionScope.

To answer your questions:

  1. The using statement will implicitly close the connection, when the connection's Dispose method is called.
  2. That should not be needed: http://aspadvice.com/blogs/name/archive/2008/05/22/Return-Within-a-C_2300_-Using-Statement.aspx
  3. Try it.

using statement will dispose the object if its class is IDisposable even there is a return statement within the using block.

It is the connection pooling that keeps your #temptable, you might want to drop that table manually.

Without knowing more about the database connection library in use, I'd guess it's neither of the first two; using was introduced specifically to make cleaning up such resources easier when returning out of methods; it's directly analogous to an ordinary try...finally block in Java or similar.

In other words, the return will leave the block and the Dispose method will be called on the connection, which should, assuming a sane implementation of such, call the Close method as part of that process.

The key point here is "sane implementation".

It's being caused by connection pooling. Wrap what you are doing in a transaction, and roll it back at the end. Or, drop the temp table after populating the ds.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top