Eu tenho um Insert
procedimento armazenado que alimentará dados Table1
e obterá o Column1
valor de Table1
e chamará o segundo procedimento armazenado que alimentará a Tabela2.
Mas quando eu chamo o segundo procedimento armazenado como:
Exec USPStoredProcName
Estou tendo o erro a seguir:
A contagem de transações após EXECUTE indica um número incompatível de instruções BEGIN e COMMIT. Contagem anterior = 1, contagem atual = 0.
Eu li as respostas em outras perguntas e não consigo encontrar exatamente onde a contagem de commits está ficando confusa.
sql
sql-server-2012
sqlexception
Vignesh Kumar A
fonte
fonte
Respostas:
Se você tiver um bloco TRY / CATCH, a causa provável é que você esteja capturando uma exceção de anulação de transação e continue. No bloco CATCH você deve sempre verificar o
XACT_STATE()
transações abortadas e não confirmadas (condenadas) apropriadas e tratá-las. Se o chamador inicia uma transação e o destinatário atinge, digamos, um deadlock (que abortou a transação), como o destinatário se comunicará ao chamador que a transação foi abortada e não deve continuar com o 'business as usual'? A única maneira viável é levantar novamente uma exceção, forçando o chamador a lidar com a situação. Se você silenciosamente engolir uma transação abortada e o chamador continuar presumindo que ainda está na transação original, apenas o caos pode garantir (e o erro que você obtém é a maneira como o mecanismo tenta se proteger).Recomendo que você repasse o tratamento de exceções e as transações aninhadas, o que mostra um padrão que pode ser usado com transações aninhadas e exceções:
fonte
xact_abort on
?if @xstate = -1 rollback;
Olhando para este exemplo MSDN , devemos não reverter a transação completa a menos que houvesse não uma transação exterior (isto é, a menos que nós fizemosbegin tran
). Eu acho que o procedimento deveria ser feito apenasrollback
se começássemos a transação, o que resolveria o problema do @parrow.Eu tive esse problema também. Para mim, o motivo era que eu estava fazendo
ao invés de
em um procedimento armazenado.
fonte
Isso normalmente acontece quando a transação é iniciada e não é confirmada ou não é rollback.
No caso de o erro vir em seu procedimento armazenado, isso pode bloquear as tabelas do banco de dados porque a transação não foi concluída devido a alguns erros de tempo de execução na ausência de tratamento de exceção. Você pode usar o tratamento de exceção como abaixo. SET XACT_ABORT
Fonte
fonte
Esteja ciente de que se você usar transações aninhadas, uma operação ROLLBACK reverterá todas as transações aninhadas, incluindo a mais externa.
Isso pode, com o uso em combinação com TRY / CATCH, resultar no erro que você descreveu. Veja mais aqui .
fonte
Isso também pode ocorrer se o procedimento armazenado encontrar uma falha de compilação após abrir uma transação (por exemplo, tabela não encontrada, nome de coluna inválido).
Eu descobri que tinha que usar 2 stored procedures, uma "worker" e uma wrapper com try / catch, ambas com lógica semelhante à descrita por Remus Rusanu. A captura do trabalhador é usada para tratar as falhas "normais" e a captura do wrapper para tratar os erros de falha de compilação.
https://msdn.microsoft.com/en-us/library/ms175976.aspx
Erros não afetados por uma construção TRY… CATCH
Espero que isso ajude alguém a economizar algumas horas de depuração ...
fonte
No meu caso, o erro estava sendo causado por um
RETURN
dentro doBEGIN TRANSACTION
. Então eu tinha algo assim:e precisa ser:
fonte
Para mim, depois de uma extensa depuração, a correção foi um simples lance perdido; declaração na captura após a reversão. Sem ele, essa mensagem de erro feia é o que você acaba recebendo.
fonte
Eu tive a mesma mensagem de erro, meu erro foi que eu tinha um ponto e vírgula no final da linha COMMIT TRANSACTION
fonte
Encontrei este erro uma vez depois de omitir esta declaração de minha transação.
fonte
Em minha opinião, a resposta aceita é, na maioria dos casos, um exagero.
A causa do erro geralmente é a incompatibilidade de BEGIN e COMMIT conforme claramente declarado pelo erro. Isso significa usar:
ao invés de
omitir Transaction após Begin causa este erro!
fonte
Certifique-se de não ter várias transações no mesmo procedimento / consulta, das quais uma ou mais não foram confirmadas.
No meu caso, acidentalmente recebi uma instrução BEGIN TRAN na consulta
fonte
Isso também pode depender da maneira como você está chamando o SP a partir de seu código C #. Se o SP retornar algum valor de tipo de tabela, invoque o SP com ExecuteStoreQuery, e se o SP não retornar nenhum valor, invoque o SP com ExecuteStoreCommand
fonte
Evite usar
declaração quando você está usando
e
instruções em procedimentos armazenados SQL
fonte
Se você tiver uma estrutura de código semelhante a:
Então use:
fonte