Когда я выполню следующее (в студии управления GO разделит команды на пакеты)
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
Я получаю сообщение об ошибке тупика. Мой процесс зашел в тупик с самим собой. Я видел это поведение в 2008, 2008R2 и 2012.
Есть ли способ использовать мой недавно созданный тип в той же транзакции, в которой он был создан?
sql-server
sql-server-2012
sql-server-2008
deadlock
Майкл Дж Сварт
источник
источник
Ответы:
Об этом сообщалось не менее четырех раз. Этот был закрыт как исправлено:
http://connect.microsoft.com/SQLServer/feedback/details/365876/
Но это было не так. (Также посмотрите раздел об обходных путях - предложенный мной обходной путь не всегда будет приемлемым.)
Этот был закрыт как задумано / не исправит:
http://connect.microsoft.com/SQLServer/feedback/details/581193/
Эти два новее
и все еще активны:http://connect.microsoft.com/SQLServer/feedback/details/800919/ (теперь закрыто, так как не будет исправлено )
http://connect.microsoft.com/SQLServer/feedback/details/804365/ (сейчас закрыто как " По дизайну" )
Пока Microsoft не убедится в обратном, вам придется искать обходной путь - просто разверните все типы перед запуском теста или разбейте его на несколько тестов.
Я постараюсь получить подтверждение от моих контактов о том, что имел в виду Умачандар, зафиксированный в самом раннем пункте, потому что, очевидно, это противоречит последующим утверждениям.
ОБНОВЛЕНИЕ № 1 (из, надеюсь, ровно 2)
Исходная ошибка (которая была закрыта как исправленная) включала псевдонимы типов, но не типа
TABLE
, Об этом сообщалось в отношении SQL Server 2005, который явно не имел табличных типов и TVP. Похоже, что UC сообщил, что ошибка с типами псевдонимов, не относящихся к таблице, была исправлена на основе того, как они обрабатывают внутренние транзакции, но она не охватывала аналогичный сценарий, который позже был представлен с типами таблиц. Я все еще жду подтверждения того, должна ли эта оригинальная ошибка когда-либо быть закрыта как исправленная; Я предложил закрыть все четыре, как задумано. Это отчасти потому, что я отчасти ожидал, что это сработает, и отчасти потому, что я понимаю, что в UC «исправление» его работы другим способом чрезвычайно сложно, может нарушить обратную совместимость и будет полезно в очень ограниченное количество вариантов использования. Ничего против вас или вашего варианта использования, но за пределами тестовых сценариев яОБНОВЛЕНИЕ № 2
Я написал в блоге об этой проблеме:
http://www.sqlperformance.com/2013/11/t-sql-queries/single-tx-deadlock
источник
Я был в состоянии воспроизвести это. График тупиков довольно любопытен:
Это выглядит для меня как ошибка, и я бы порекомендовал вам открыть элемент подключения для него.
Чтобы обойти вашу непосредственную проблему, вы можете использовать
tSQLt.NewConnection
(я полагаю, вы используете tSQLt)Я до сих пор не понимаю, откуда возникла необходимость создания табличного типа на лету, и я полагаю, что вы слишком усложняете свой тест. Отправьте мне письмо, если хотите обсудить.
источник
Если кто-то не знает другого, я не думаю, что есть способ сделать это за одну транзакцию. Я не думаю, что это ошибка.
Во-первых, вам нужно взять блокировку модификации схемы (Sch-M) при создании типа. Поскольку вы не фиксируете транзакцию, блокировка остается открытой. Затем вы пытаетесь объявить переменную этого типа в той же транзакции. Это пытается взять схему стабильности схемы (Sch-S). Эти два типа несовместимы одновременно на одном и том же объекте. Поскольку они находятся в одной транзакции, SQL рассматривает это как тупик, потому что Sch-S никогда не может быть предоставлен, пока транзакция открыта.
Запускайте каждый пакет по одному и выбирайте sys.dm_tran_locks, как только вы попытаетесь объявить переменную. Вы увидите тот же процесс, удерживающий Sch-M и ожидающий Sch-S на том же объекте.
источник