uma instrução de retorno pode impedir que um usando declaração de fechar uma conexão com um banco de dados?

StackOverflow https://stackoverflow.com/questions/588396

Pergunta

Quando estou criando tabelas temporárias recebo uma mensagem de erro dizendo que que a tabela temporária já existe. A tabela temporária é exclusivo para a sessão assim que parece a minha conexão não está fechando corretamente e eu acho que pode ter algo a ver com uma instrução de retorno que tenho na minha instrução using.

Eu tenho o seguinte código:

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

Eu uso este tipo de código em vários lugares para criar uma tabela temporária com o mesmo nome.

Infelizmente, eu estou recebendo o seguinte erro:. There is already an object named '#MyTempTable' in the database

Agora, eu sei que a tabela temporária é exclusivo para a sessão e então uma vez que a sessão é fechada deve desaparecer.

Há três coisas que eu acredito que pode causar este ...

  1. Eu preciso chamar Connection.Close ()
  2. Eu preciso colocar a instrução de retorno de fora da minha instrução usando
  3. I precisa soltar a tabela temporária que eu criei antes de retornar

Alguém sabe qual é? ou se é algo que eu não tenha pensado?

Foi útil?

Solução

Eu estou supondo aqui, mas verificar as configurações de sua conexão de banco de dados pooling. Tente ligar pooling fora e ver se isso ajuda.

Normalmente, quando você fechar / conexão dispor sobre o nível de bibliotecas .NET, conexão com o servidor de banco de dados real não é fechado. É acabado de voltar para o pool de conexão do provedor de dados dentro e será reutilizado quando o programa pede outra ligação com os mesmos parâmetros e credenciais. Eu não acho sessão de banco de dados é reposto de qualquer maneira antes de ser devolvido para a piscina, exceto para transações abertas e talvez alguns parâmetros básicos. objetos mais caros, como tabelas temporárias, são deixados sozinhos.

Você pode ativar pooling off (muito ineficiente). Ou você pode verificar a existência tabela temporária antes de tentar criá-lo e apagar seu conteúdo se ele existir. Ou você pode soltar tabela temporária antes de fechar conexão.

Outras dicas

Eu tenho quase certeza que connection.Dispose () (e, portanto, Connection.Close () também) será chamado.

Você pode verificar que com bastante facilidade, fazendo 1) e 2) e verificar se o problema ainda existe. A solução é, provavelmente, 3) ea explicação seria pool de conexão.

A menos que um ciclo de energia ocorre ou algum outro seriamente bizarro dispor canto caso será chamado.

Se você quiser embalagem à prova o objeto e colocar um ponto de interrupção no.

A utilizando bloco é convertido em uma tentativa / captura / finalmente bloquear sob o capô. Sim, vai dispor, independentemente do retorno dentro do bloco usando.

Não, Connection.Close será sempre chamado porque internamente usando coloca-lo em um try / finally bloco.

Você também pode querer considerar o pool de conexão. Tentar envolver seu código em um TransactionScope.

Para responder às suas perguntas:

  1. A instrução using vai implicitamente fechar a ligação, quando método Dispose da conexão é chamada.
  2. Isso não deve ser necessário: http://aspadvice.com/blogs/name/archive/2008/05/22/Return-Within-a-C_2300_-Using-Statement.aspx
  3. Tente.

usando declaração irá descartar o objeto se sua classe é IDisposable ainda há uma instrução de retorno dentro do bloco usando.

É o pool de conexão que mantém o seu #temptable, você pode querer deixar que a tabela manualmente.

Sem saber mais sobre a biblioteca de conexões de banco de dados em uso, eu acho que é nenhum dos dois primeiros; using foi introduzida especificamente para fazer a limpeza de tais recursos mais fácil quando retornar fora de métodos; é diretamente análogo a um bloco try...finally comum em Java ou similar.

Em outras palavras, o return vai deixar o bloco eo método Dispose será chamado na conexão, que deve, assumindo uma implementação sane de tal, chame o método Close como parte desse processo.

O ponto-chave aqui é "implementação sã".

Ele está sendo causada por pool de conexão. Enrole o que está fazendo em uma transação, e enrolá-lo de volta no final. Ou, deixe cair a tabela temporária depois de preencher os ds.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top