Quando executo o seguinte (no estúdio de gerenciamento, o GO separará os comandos em lotes)
use tempdb
begin tran
go
CREATE TYPE dbo.IntIntSet AS TABLE(
Value0 Int NOT NULL,
Value1 Int NOT NULL
)
go
declare @myPK dbo.IntIntSet;
go
rollback
Recebo uma mensagem de erro de conflito. Meu processo entrou em conflito consigo mesmo. Eu já vi esse comportamento em 2008, 2008R2 e 2012.
Existe uma maneira de usar meu tipo recém-criado dentro da mesma transação que foi criada?
sql-server
sql-server-2012
sql-server-2008
deadlock
Michael J Swart
fonte
fonte
Respostas:
Isso foi relatado nada menos que quatro vezes. Este foi fechado como corrigido:
http://connect.microsoft.com/SQLServer/feedback/details/365876/
Mas isso não era verdade. (Observe também a seção de soluções alternativas - a solução que sugeri nem sempre será aceitável.)
Este foi fechado como por design / não será corrigido:
http://connect.microsoft.com/SQLServer/feedback/details/581193/
Estes dois são mais novos
e ainda ativos:http://connect.microsoft.com/SQLServer/feedback/details/800919/ (agora fechado como não será corrigido )
http://connect.microsoft.com/SQLServer/feedback/details/804365/ (agora fechado como por design )
Até que a Microsoft possa se convencer do contrário, você precisará encontrar uma solução alternativa - basta ter todos os tipos implantados antes de executar seu teste ou dividi-lo em vários testes.
Tentarei obter confirmação de meus contatos sobre o que Umachandar quis dizer com corrigido no item mais antigo, porque obviamente isso entra em conflito com declarações posteriores.
ATUALIZAÇÃO # 1 (de, espero, exatamente 2)
O bug original (que foi fechado como corrigido) envolvia tipos de alias, mas não do tipo
TABLE
. Foi relatado no SQL Server 2005, que obviamente não tinha tipos de tabela e TVPs. Parece que a UC relatou que o bug com tipos de alias que não são de tabela foi corrigido com base em como eles lidam com transações internas, mas não cobriu um cenário semelhante posteriormente introduzido nos tipos de tabela. Ainda estou aguardando a confirmação de que o bug original deveria ter sido fechado como corrigido; Sugeri que todos os quatro fossem fechados como planejado. Isso ocorre em parte porque é do tipo que eu esperava que funcionasse, e em parte porque eu entendo pela UC que "corrigi-lo" para funcionar de uma maneira diferente é extremamente complexo, poderia quebrar a compatibilidade com versões anteriores e seria útil em alguns casos. número muito limitado de casos de uso. Nada contra você ou seu caso de uso, mas fora dos cenários de teste, eu 'ATUALIZAÇÃO # 2
Eu escrevi sobre esse problema no blog:
http://www.sqlperformance.com/2013/11/t-sql-queries/single-tx-deadlock
fonte
Eu era capaz de reproduzir isso. O gráfico de deadlock é bastante curioso:
Parece-me um bug e eu recomendo que você abra um item de conexão para ele.
Para solucionar seu problema imediato, você pode usar
tSQLt.NewConnection
(presumo que você esteja usando o tSQLt)Ainda não entendo de onde vem a necessidade de criar um tipo de tabela rapidamente e presumo que você esteja complicando demais o teste. Envie-me um e-mail se você quiser discutir.
fonte
A menos que alguém saiba diferente, não acho que haja uma maneira de fazer isso em uma única transação. Eu não acho que isso seja um bug.
Primeiro, você precisa fazer um bloqueio de modificação de esquema (Sch-M) ao criar o tipo. Como você não confirma a transação, o bloqueio permanece aberto. Então você tenta declarar uma variável para esse tipo na mesma transação. Isso tenta usar um bloqueio de estabilidade do esquema (Sch-S). Esses dois tipos são incompatíveis simultaneamente no mesmo objeto. Como eles estão na mesma transação, o SQL o trata como um impasse, porque o Sch-S nunca pode ser concedido enquanto a transação está aberta.
Execute cada lote, um de cada vez, e selecione sys.dm_tran_locks assim que tentar declarar a variável. Você verá o mesmo processo segurando um Sch-M e aguardando um Sch-S no mesmo objeto.
fonte