Wenn ich Folgendes ausführe (in Management Studio werden die Befehle von GO in Stapel aufgeteilt)
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
Ich erhalte eine Deadlock-Fehlermeldung. Mein Prozess hat mit sich selbst festgefahren. Ich habe dieses Verhalten in 2008, 2008R2 und 2012 gesehen.
Gibt es eine Möglichkeit, meinen neu erstellten Typ in derselben Transaktion zu verwenden, in der er erstellt wurde?
sql-server
sql-server-2012
sql-server-2008
deadlock
Michael J Swart
quelle
quelle
Antworten:
Dies wurde nicht weniger als vier Mal gemeldet. Dieser wurde als behoben geschlossen:
http://connect.microsoft.com/SQLServer/feedback/details/365876/
Das stimmte aber nicht. (Sehen Sie sich auch den Abschnitt mit den Problemumgehungen an - die von mir vorgeschlagene Problemumgehung ist nicht immer akzeptabel.)
Dieser wurde absichtlich geschlossen / wird nicht repariert:
http://connect.microsoft.com/SQLServer/feedback/details/581193/
Diese beiden sind neuer
und immer noch aktiv:http://connect.microsoft.com/SQLServer/feedback/details/800919/ (jetzt geschlossen als Won't Fix )
http://connect.microsoft.com/SQLServer/feedback/details/804365/ (jetzt geschlossen als By Design )
Solange Microsoft nicht davon überzeugt ist, müssen Sie eine Problemumgehung finden. Stellen Sie einfach alle Typen bereit, bevor Sie den Test ausführen, oder teilen Sie ihn in mehrere Tests auf.
Ich werde versuchen, von meinen Kontakten eine Bestätigung darüber zu erhalten, was Umachandar unter dem frühesten Punkt verstanden hat, da dies offensichtlich im Widerspruch zu späteren Aussagen steht.
UPDATE # 1 (von hoffentlich genau 2)
Der ursprüngliche Fehler (der als behoben geschlossen wurde) betraf Alias-Typen, jedoch keine Typen
TABLE
. Es wurde gegen SQL Server 2005 gemeldet, das offensichtlich keine Tabellentypen und TVPs hatte. Es scheint, dass UC berichtet hat, dass der Fehler mit Nicht-Tabellen-Alias-Typen behoben wurde, basierend auf der Art und Weise, wie interne Transaktionen behandelt werden. Ein ähnliches Szenario, das später mit Tabellentypen eingeführt wurde, wurde jedoch nicht behandelt. Ich warte immer noch auf die Bestätigung, ob dieser ursprüngliche Fehler jemals als behoben hätte geschlossen werden sollen. Ich habe vorgeschlagen, alle vier wie beabsichtigt zu schließen. Dies liegt zum Teil daran, dass ich erwartet habe, dass es funktioniert, und zum Teil daran, dass ich von UC das Gefühl bekomme, dass es extrem komplex ist, die Abwärtskompatibilität aufheben könnte und hilfreich für eine sehr begrenzte Anzahl von Anwendungsfällen. Nichts gegen Sie oder Ihren Anwendungsfall, aber außerhalb der TestszenarienUPDATE # 2
Ich habe über dieses Problem gebloggt:
http://www.sqlperformance.com/2013/11/t-sql-queries/single-tx-deadlock
quelle
Ich konnte das reproduzieren. Das Deadlock-Diagramm ist ziemlich merkwürdig:
Es sieht für mich wie ein Fehler aus und ich würde empfehlen, dass Sie ein Verbindungselement dafür öffnen.
Um Ihr unmittelbares Problem zu
tSQLt.NewConnection
umgehen, können Sie Folgendes verwenden (ich gehe davon aus, dass Sie tSQLt verwenden)Ich verstehe immer noch nicht, woher die Notwendigkeit kommt, einen Tabellentyp im laufenden Betrieb zu erstellen, und ich gehe davon aus, dass Sie Ihren Test zu kompliziert machen. Senden Sie mir eine E-Mail, wenn Sie diskutieren möchten.
quelle
Ich glaube nicht, dass es eine Möglichkeit gibt, dies in einer einzigen Transaktion zu tun, es sei denn, jemand weiß etwas anderes. Ich denke nicht, dass dies ein Fehler ist.
Zunächst müssen Sie beim Erstellen des Typs eine Schemamodifikationssperre (Sch-M) aktivieren. Da Sie die Transaktion nicht festschreiben, bleibt das Schloss geöffnet. Anschließend versuchen Sie, in derselben Transaktion eine Variable für diesen Typ zu deklarieren. Dadurch wird versucht, eine Schemastabilitätssperre (Sch-S) zu übernehmen. Diese beiden Typen sind auf demselben Objekt gleichzeitig inkompatibel. Da sie sich in derselben Transaktion befinden, wird dies von SQL als Deadlock behandelt, da Sch-S niemals gewährt werden kann, solange die Transaktion geöffnet ist.
Führen Sie jeden Stapel einzeln aus und wählen Sie sys.dm_tran_locks aus, sobald Sie versuchen, die Variable zu deklarieren. Sie werden sehen, wie derselbe Prozess ein Sch-M hält und auf ein Sch-S für dasselbe Objekt wartet.
quelle