Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Вставка строки  [new]
leov
Member

Откуда: С-Петербург
Сообщений: 616
invm
leov
это как она может быь возможна?
Еще как возможна. Если нет ограничения уникальности. Если есть, то в одном из сеансов будет ошибка вставки дубликата ключа.
Вы почему-то считаете, что insert в разных сеансах выстроятся в очередь, а это не так.
извините, не понимаю
инсерт проходит только в случае если not exists
мне кажется что между проверкой not exists и собственно инсертом нет зазора в который кто-то может вклинится
т.е вся операция инсерта атомарна
разьве не так?
12 янв 14, 16:15    [15404679]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
leov
invm
пропущено...
Еще как возможна. Если нет ограничения уникальности. Если есть, то в одном из сеансов будет ошибка вставки дубликата ключа.
Вы почему-то считаете, что insert в разных сеансах выстроятся в очередь, а это не так.
извините, не понимаю
инсерт проходит только в случае если not exists
мне кажется что между проверкой not exists и собственно инсертом нет зазора в который кто-то может вклинится
т.е вся операция инсерта атомарна
разьве не так?
не так
12 янв 14, 16:17    [15404681]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
leov
Member

Откуда: С-Петербург
Сообщений: 616
iap
leov
пропущено...
извините, не понимаю
инсерт проходит только в случае если not exists
мне кажется что между проверкой not exists и собственно инсертом нет зазора в который кто-то может вклинится
т.е вся операция инсерта атомарна
разьве не так?
не так
пояснить можете
хотелось бы услышать ответ отличный от "могу"
12 янв 14, 16:51    [15404749]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
sdet
Member

Откуда:
Сообщений: 463
leov
iap
пропущено...
не так
пояснить можете
хотелось бы услышать ответ отличный от "могу"

Может объясните почему между проверкой not exists и собственно инсертом нет зазора в который кто-то может вклинится?
12 янв 14, 17:04    [15404778]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
leov
Member

Откуда: С-Петербург
Сообщений: 616
sdet
leov
пропущено...
пояснить можете
хотелось бы услышать ответ отличный от "могу"

Может объясните почему между проверкой not exists и собственно инсертом нет зазора в который кто-то может вклинится?
я же выше написал что считаю что оперция инсерта вместе со всеми потрохами(проверками и пр) атомарна
вы можете это аргументированно опровергнуть?
12 янв 14, 17:23    [15404817]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
sdet
Member

Откуда:
Сообщений: 463
leov
sdet
пропущено...

Может объясните почему между проверкой not exists и собственно инсертом нет зазора в который кто-то может вклинится?
я же выше написал что считаю что оперция инсерта вместе со всеми потрохами(проверками и пр) атомарна
вы можете это аргументированно опровергнуть?

Вы где-то увидели это в документации? С чего вы это взяли? Опровержению подлежит обратное, а не очевидное.
12 янв 14, 17:28    [15404831]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
leov
Member

Откуда: С-Петербург
Сообщений: 616
sdet,

послушайте, я не ищу конфликта и не препираюсь ради прикола
я давно занимаюсь sql и одним из основных принципов sql считаю что операции в нем атомарны
из многолетней практики я ни разу не сталкивался со случаями опровергеющими это
если это не так то я вообще не знаю как можно реализовать подобные задачи
ну разьве что оборачивать инсерт в try catch и если инсерт не прошел то апдейтить

я не помню откуда уже такое убеждение, вероятно из книжек, больших доказательств к сожалению не имею
если вы правда знаете в чем я ошибаюсь или доказательство вашей правоты
то прошу сказать, буду очень благодарен
12 янв 14, 17:48    [15404872]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Неоднократно мы это тут обсуждали.
Вот, например: https://www.sql.ru/forum/544644-1/insert-select-i-tranzakcii
И про неатомарность MERGE было...
12 янв 14, 17:50    [15404879]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
leov
sdet,

послушайте, я не ищу конфликта и не препираюсь ради прикола
я давно занимаюсь sql и одним из основных принципов sql считаю что операции в нем атомарны
из многолетней практики я ни разу не сталкивался со случаями опровергеющими это
если это не так то я вообще не знаю как можно реализовать подобные задачи
ну разьве что оборачивать инсерт в try catch и если инсерт не прошел то апдейтить

я не помню откуда уже такое убеждение, вероятно из книжек, больших доказательств к сожалению не имею
если вы правда знаете в чем я ошибаюсь или доказательство вашей правоты
то прошу сказать, буду очень благодарен
Атомарность и изоляция транзакции - разные вещи, правда?
Собственно, об этом обсуждение по данной мною ссылке...
12 янв 14, 17:52    [15404884]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
leov
я же выше написал что считаю что оперция инсерта вместе со всеми потрохами(проверками и пр) атомарна
Ну если вы так считаете, то должны знать какими механизмами такая атомарность обеспечивается. Вот и расскажите нам про них.
12 янв 14, 17:52    [15404885]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
leov
я давно занимаюсь sql и одним из основных принципов sql считаю что операции в нем атомарны
В 15404574 демонстрируется неатомарность merge. Вы можете его самостоятельно адаптировать для insert-select.
12 янв 14, 17:58    [15404908]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
leov
Member

Откуда: С-Петербург
Сообщений: 616
iap
Неоднократно мы это тут обсуждали.
Вот, например: https://www.sql.ru/forum/544644-1/insert-select-i-tranzakcii
И про неатомарность MERGE было...
вот блин откровение
надо изучать и осознавать
спасибо
12 янв 14, 18:51    [15405090]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
pkarklin
Проверять их правоту следует запустив несколько (пару сотен) вызовов одновременно, а не использовать профайлер.
Лучше уж поставить WaitFor, а в рамках одного запроса правильным подстановки локировочной таблицы.
pkarklin
Интересный способ отслеживания накладываемых блокировок планом выполнения.
Эээ, а разве это неправильно? Он хотя бы правильно направит. А далее уже если не доверяешь можно и на практике писать разнообразные тесты.

Использовать профайлер мне кажется более уместным - сразу дреть в корень, чем ошибиться на плохо организованном тесте.

IMXO.

invm
Merge без serializable не работает как надо. Это легко проверяется.
Туды её в качель. Это подло, если так.
Логика описания задачи в MERGE запросе однозначно говорит как надо ставить локировки.
invm
tools.clrfnWT_Delay(10000) = 1/*Задержка 10 сек*/
Хитро. Но я обычно вместо этого ставлю чтение некой таблы, на которую отдельно вешаю несовмещаемый лок. Ручная задержка.


Я считаю что это баг, ибо остальные команды всегда работают логически корректно в рамках этой команды.
Команда должна быть атомарна, в рамках логической строки.
12 янв 14, 19:19    [15405171]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
iap
Неоднократно мы это тут обсуждали.
Вот, например: https://www.sql.ru/forum/544644-1/insert-select-i-tranzakcii
И про неатомарность MERGE было...
В той теме не про MERGE.
INSERT SELECT нельзя считать атомарным там нет связки (между сущностью INSERT и SELECT, точнее EXISTS внутрях). Более того это две отдельные команды связанные только пипелайном. Они целостны по выполнению но не консистентны.

В MERGE есть явно связка, даже не связка а единство сущности. Более того - это единственный смысл MERGE.
12 янв 14, 19:30    [15405213]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
бл?*:!. Ну и подстава со стороны M$.

Поохожая история как с CTE. Сначала всё было клёво, потом нашли проблему (в данном случае с производительностью и локами), а потом забили на решение (или быстро заглушку наваяли) - надо же выставлять в продакшин, начайсто требует. И в итоге имеем то что имеем, а потом пресловутая обратная совместимость багов.

Пидарасы.
12 янв 14, 19:39    [15405243]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Mnior
iap
Неоднократно мы это тут обсуждали.
Вот, например: https://www.sql.ru/forum/544644-1/insert-select-i-tranzakcii
И про неатомарность MERGE было...
В той теме не про MERGE.
INSERT SELECT нельзя считать атомарным там нет связки (между сущностью INSERT и SELECT, точнее EXISTS внутрях). Более того это две отдельные команды связанные только пипелайном. Они целостны по выполнению но не консистентны.

В MERGE есть явно связка, даже не связка а единство сущности. Более того - это единственный смысл MERGE.
Да было и про MERGE, найти не смог...
Когда SQL2008 только вышел, по-моему, об этом писал Decolo®es. А может, и не он... Не уверен.
12 янв 14, 20:13    [15405336]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Михаил1989
Guest
Верно ли я понимаю, что и в примере

Блокировки и конструкция update ... from ... inner join ...

Мы можем получить ситуацию, когда обновленные данные (рассчитанные в from) на момент обновления не будут соответствовать реальному положению дел в базе (при read committed?).
12 янв 14, 20:14    [15405339]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Михаил1989
Guest
Ну и получаем гонку при записи - кто первый того и тапки. И может получиться ситуация

update
from
t1
inner join
(
...
)

worker1 считал и посчитал данные на основе других таблиц и уснул,
worker2 добавил данные и посчитал все что есть и обновил результат
worker1 проснулся и обновил результат
12 янв 14, 20:17    [15405347]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Михаил1989
Мы можем получить ситуацию, когда обновленные данные (рассчитанные в from) на момент обновления не будут соответствовать реальному положению дел в базе (при read committed?).
Можем.
12 янв 14, 20:59    [15405419]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Михаил1989,

Эта операция атомарна, а обсуждается две отдельные операции подрят и оператор MERGE.

автор
worker1 считал и посчитал данные на основе других таблиц и уснул,
worker2 добавил данные и посчитал все что есть и обновил результат
worker1 проснулся и обновил результат
если worker1 прочитал данные, значит они залокированны.
worker2 не сможет поменять результат т.к. первый их держит.

Если поменять запрос на явный JOIN. То допустим (что кстати ещё не факт) сначала будет срабатывать запрос (tbl1, tbl2), и должна висеть Range локировка, а далее будет замена.
Даже если будет что порядок двух запросов изменится, то логика нарушаться не будет. Оба запроса дают одинаковый результат, никакая вставка не просочится (tbl1, tbl2). Разве что может быть почти нереальный дедлок (если оба запроса поменяют хотя бы по сроке и потом пересекутся). [поэтому MS предпочитает упорядоченные данные, и при выборе планов]
Если первый не успеет что либо поменять, то нет никакой разницы начал он считывать до второго или нет. Всё консистентно.
12 янв 14, 21:01    [15405421]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
invm
Можем.
Я не гарантирую, но range кажись бывают и при RC.
Хотя я могу путать с Exists / NOT Exist где по логике хватает лока на одну строку / диапазон.
Надо пруфы.
12 янв 14, 21:06    [15405426]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Mnior
То допустим (что кстати ещё не факт) сначала будет срабатывать запрос (tbl1, tbl2), и должна висеть Range локировка, а далее будет замена.
Что-то я размечтался.
Да для Exists-ов всё понятно, там построчное, а для группировок / агрегаток идёт классическая проблема с фантомами.
Более того, в данном случае даже не держится ни одной локировки в этом ключе - MS просто умывает руки.
+ Тест
USE tempdb
CREATE TABLE dbo.T1 (ID Int PRIMARY KEY, Value Int NULL)
CREATE TABLE dbo.T2 (ID Int PRIMARY KEY, Obj Int, Date Date, Value Int)
CREATE INDEX IX_T2 ON dbo.T2 (Date)INCLUDE(Obj,Value)

INSERT dbo.T1 (ID) VALUES (1),(2),(3)
INSERT dbo.T2 VALUES (1,2,'20130101',1)

UPDATE	T1
SET	Value = S.[Sum]
FROM (	SELECT	T2.Obj
	,	Sum(T2.Value)	AS [Sum]
	FROM	dbo.T2	T2
	WHERE	T2.Date >= '20130101'
	AND	T2.Date <  '20140101'
	GROUP BY T2.Obj)S
JOIN	dbo.T1		T1 ON T1.ID = S.Obj

DROP TABLE dbo.T2, dbo.T1;
21553310Lock:Acquired8 - IX5 - OBJECT13491250621349125062
21553311Lock:Acquired6 - IS5 - OBJECT14131252901413125290
21553312Lock:Acquired6 - IS6 - PAGE084308172657331404801:2526
21553313Lock:Acquired3 - S7 - KEY08430817265733140480(49648ba0148f)
21553314Lock:Released3 - S7 - KEY08430817265733140480(49648ba0148f)
21553315Lock:Released6 - IS6 - PAGE084308172657331404801:2526
21553316Lock:Acquired7 - IU6 - PAGE082867020775753646081:2475
21553317Lock:Acquired4 - U7 - KEY08286702077575364608(61a06abd401c)
21553318Lock:Acquired8 - IX6 - PAGE082867020775753646081:2475
21553319Lock:Acquired5 - X7 - KEY08286702077575364608(61a06abd401c)
21553320Lock:Released0 - NULL7 - KEY08286702077575364608(61a06abd401c)
21553321Lock:Released0 - NULL6 - PAGE082867020775753646081:2475
21553322Lock:Released6 - IS5 - OBJECT14131252901413125290
21553323Lock:Released5 - X7 - KEY08286702077575364608(61a06abd401c)
21553324Lock:Released8 - IX6 - PAGE082867020775753646081:2475
21553325Lock:Released8 - IX5 - OBJECT13491250621349125062
И ставится давний вопрос - "где RangeLock хинт ?". Ну не хочу я держать Range-S локировку до конца транзакции, а только до конца изменения этой строки. Хотя из запросов (практически всех) можно очевиднейшим образом догадаться как ставить и снимать локировки.

Ну я согласен что в общем такие запросы практически огромная редкость и Range - практически гарантия проблем, но хинты должны быть.
И согласен что если надо надёжно то SERIALIZE для одной команды подойдёт, а если из много то более вероятней оно нужно для них всех.
То есть на практике не проблема, не такая сильная, но для Enterprize ИМХО хинт нужен.

MERGE
Может быть ситуация когда выгодно сначала считать данные из источника, а потом проверить если они или нет в основной табле и сделать соответствующие действия. Перед изменениями идёт чтение из основной таблы (которые JOIN-ятся, и на основании которых делается решение). Имеющиеся строки то лочатся (U), но тех которых нет - нельзя ничего наложить, ибо неизвестно ещё что туда будет вставка и нельзя диапазон указать. Это справедливо для Merge-Join, в случае же Loop-Join SEEK даёт инфу о месте вставки и U/RangeI можно навесить.
+ но нет же
USE tempdb
CREATE TABLE dbo.T1 (ID Int PRIMARY KEY, Value Int)

DELETE dbo.T1;

WITH [Source] (ID,Value) AS (SELECT 1,1)
MERGE	dbo.T1	T
USING	[Source]S ON T.ID = S.ID
WHEN	    MATCHED THEN UPDATE SET Value = S.Value
WHEN	NOT MATCHED THEN INSERT VALUES (ID,Value);

DROP TABLE dbo.T1;
21605112Lock:Acquired8 - IX5 - OBJECT569366358569366358
21605113Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21605114Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21605115Lock:Released4 - U7 - KEY01729461194654482432(8194443284a0)
21605116Lock:Released7 - IU6 - PAGE017294611946544824321:2032
21605117Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21605118Lock:Acquired15 - RangeI-N7 - KEY01729461194654482432(8194443284a0)
21605119Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21605120Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21605121Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21605122Lock:Released8 - IX5 - OBJECT569366358569366358
21605124Lock:Acquired8 - IX5 - OBJECT569366358569366358
21605125Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21605126Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21605127Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21605128Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21605129Lock:Released0 - NULL7 - KEY01729461194654482432(8194443284a0)
21605130Lock:Released0 - NULL6 - PAGE017294611946544824321:2032
21605131Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21605132Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21605133Lock:Released8 - IX5 - OBJECT569366358569366358
Она то навешивается и ... потом снимается, аккурат перед вставкой - LOL.
+ на хинтах
WITH [Source] (ID,Value) AS (SELECT 1,1)
MERGE	dbo.T1	WITH (UpdLock) T
USING	[Source]S ON T.ID = S.ID
WHEN	    MATCHED THEN UPDATE SET Value = S.Value
WHEN	NOT MATCHED THEN INSERT VALUES (ID,Value);
21637260Lock:Acquired8 - IX5 - OBJECT569366358569366358
21637261Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21637262Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21637263Lock:Released0 - NULL7 - KEY01729461194654482432(8194443284a0)
21637264Lock:Released0 - NULL6 - PAGE017294611946544824321:2032
21637265Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21637266Lock:Acquired15 - RangeI-N7 - KEY01729461194654482432(8194443284a0)
21637267Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21637268Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21637269Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21637270Lock:Released8 - IX5 - OBJECT569366358569366358
21637866Lock:Acquired8 - IX5 - OBJECT569366358569366358
21637867Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21637868Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21637869Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21637870Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21637871Lock:Released0 - NULL7 - KEY01729461194654482432(8194443284a0)
21637872Lock:Released0 - NULL6 - PAGE017294611946544824321:2032
21637873Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21637874Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21637875Lock:Released8 - IX5 - OBJECT569366358569366358

WITH [Source] (ID,Value) AS (SELECT 1,1)
MERGE	dbo.T1	WITH (HoldLock) T
USING	[Source]S ON T.ID = S.ID
WHEN	    MATCHED THEN UPDATE SET Value = S.Value
WHEN	NOT MATCHED THEN INSERT VALUES (ID,Value);
21640902Lock:Acquired8 - IX5 - OBJECT569366358569366358
21640903Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21640904Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21640905Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21640906Lock:Acquired15 - RangeI-N7 - KEY01729461194654482432(8194443284a0)
21640907Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21640908Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21640909Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21640910Lock:Released8 - IX5 - OBJECT569366358569366358
21640924Lock:Acquired8 - IX5 - OBJECT569366358569366358
21640925Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21640926Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21640927Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21640928Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21640929Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21640930Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21640931Lock:Released8 - IX5 - OBJECT569366358569366358

WITH [Source] (ID,Value) AS (SELECT 1,1)
MERGE	dbo.T1	WITH (UpdLock, HoldLock) T
USING	[Source]S ON T.ID = S.ID
WHEN	    MATCHED THEN UPDATE SET Value = S.Value
WHEN	NOT MATCHED THEN INSERT VALUES (ID,Value);
21642785Lock:Acquired8 - IX5 - OBJECT569366358569366358
21642786Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21642787Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21642788Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21642789Lock:Acquired15 - RangeI-N7 - KEY01729461194654482432(8194443284a0)
21642790Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21642791Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21642792Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21642793Lock:Released8 - IX5 - OBJECT569366358569366358
21642812Lock:Acquired8 - IX5 - OBJECT569366358569366358
21642813Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21642814Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21642815Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21642816Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21642817Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21642818Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21642819Lock:Released8 - IX5 - OBJECT569366358569366358
Подойдёт любой, только с HoldLock меньше лишних действий / event-ов. Но это для Loop-Join
invm
Merge без serializable не работает как надо. Это легко проверяется.
А если будет Merge-Join ?
+ Тест
USE tempdb
CREATE TABLE dbo.T1 (ID Int PRIMARY KEY, Value Int)
CREATE TABLE dbo.T2 (ID Int PRIMARY KEY, Value Int)
INSERT dbo.T2 VALUES (1,1)

DELETE dbo.T1;

WITH [Source] (ID,Value) AS (SELECT 1,1)
MERGE	dbo.T1	T
USING	dbo.T2	S ON T.ID = S.ID
WHEN	    MATCHED THEN UPDATE SET Value = S.Value
WHEN	NOT MATCHED THEN INSERT VALUES (ID,Value)
OPTION (MERGE JOIN);

DROP TABLE dbo.T1;
21694948Lock:Acquired8 - IX5 - OBJECT569366358569366358
21694949Lock:Acquired6 - IS5 - OBJECT259897358259897358
21694950Lock:Acquired6 - IS6 - PAGE074220113680591093761:4562
21694951Lock:Acquired3 - S7 - KEY07422011368059109376(8194443284a0)
21694952Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21694953Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21694954Lock:Released7 - IU6 - PAGE017294611946544824321:2032
21694955Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21694956Lock:Acquired15 - RangeI-N7 - KEY01729461194654482432(8194443284a0)
21694957Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21694958Lock:Released3 - S7 - KEY07422011368059109376(8194443284a0)
21694959Lock:Released6 - IS6 - PAGE074220113680591093761:4562
21694960Lock:Released6 - IS5 - OBJECT259897358259897358
21694961Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21694962Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21694963Lock:Released8 - IX5 - OBJECT569366358569366358
21694992Lock:Acquired8 - IX5 - OBJECT569366358569366358
21694993Lock:Acquired6 - IS5 - OBJECT259897358259897358
21694994Lock:Acquired6 - IS6 - PAGE074220113680591093761:4562
21694995Lock:Acquired3 - S7 - KEY07422011368059109376(8194443284a0)
21694996Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21694997Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21694998Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21694999Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21695000Lock:Released0 - NULL7 - KEY01729461194654482432(8194443284a0)
21695001Lock:Released0 - NULL6 - PAGE017294611946544824321:2032
21695002Lock:Released3 - S7 - KEY07422011368059109376(8194443284a0)
21695003Lock:Released6 - IS6 - PAGE074220113680591093761:4562
21695004Lock:Released6 - IS5 - OBJECT259897358259897358
21695005Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21695006Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21695007Lock:Released8 - IX5 - OBJECT569366358569366358
WITH [Source] (ID,Value) AS (SELECT 1,1)
MERGE	dbo.T1	WITH (HoldLock)	T
USING	dbo.T2	S ON T.ID = S.ID
WHEN	    MATCHED THEN UPDATE SET Value = S.Value
WHEN	NOT MATCHED THEN INSERT VALUES (ID,Value)
OPTION (MERGE JOIN);
21677458Lock:Acquired8 - IX5 - OBJECT569366358569366358
21677459Lock:Acquired6 - IS5 - OBJECT259897358259897358
21677460Lock:Acquired6 - IS6 - PAGE074220113680591093761:4562
21677461Lock:Acquired3 - S7 - KEY07422011368059109376(8194443284a0)
21677462Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21677463Lock:Acquired14 - RangeS-U7 - KEY01729461194654482432(8194443284a0)
21677464Lock:Acquired14 - RangeS-U7 - KEY01729461194654482432(ffffffffffff)
21677465Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21677466Lock:Acquired15 - RangeI-N7 - KEY01729461194654482432(8194443284a0)
21677467Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21677468Lock:Released3 - S7 - KEY07422011368059109376(8194443284a0)
21677469Lock:Released6 - IS6 - PAGE074220113680591093761:4562
21677470Lock:Released6 - IS5 - OBJECT259897358259897358
21677471Lock:Released14 - RangeS-U7 - KEY01729461194654482432(ffffffffffff)
21677472Lock:Released21 - RangeX-X7 - KEY01729461194654482432(8194443284a0)
21677473Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21677474Lock:Released8 - IX5 - OBJECT569366358569366358
21677520Lock:Acquired8 - IX5 - OBJECT569366358569366358
21677521Lock:Acquired6 - IS5 - OBJECT259897358259897358
21677522Lock:Acquired6 - IS6 - PAGE074220113680591093761:4562
21677523Lock:Acquired3 - S7 - KEY07422011368059109376(8194443284a0)
21677524Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21677525Lock:Acquired14 - RangeS-U7 - KEY01729461194654482432(8194443284a0)
21677526Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21677527Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21677528Lock:Acquired14 - RangeS-U7 - KEY01729461194654482432(ffffffffffff)
21677529Lock:Released3 - S7 - KEY07422011368059109376(8194443284a0)
21677530Lock:Released6 - IS6 - PAGE074220113680591093761:4562
21677531Lock:Released6 - IS5 - OBJECT259897358259897358
21677532Lock:Released14 - RangeS-U7 - KEY01729461194654482432(ffffffffffff)
21677533Lock:Released21 - RangeX-X7 - KEY01729461194654482432(8194443284a0)
21677534Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21677535Lock:Released8 - IX5 - OBJECT569366358569366358

WITH [Source] (ID,Value) AS (SELECT 1,1)
MERGE	dbo.T1	WITH (UpdLock)	T
USING	dbo.T2	S ON T.ID = S.ID
WHEN	    MATCHED THEN UPDATE SET Value = S.Value
WHEN	NOT MATCHED THEN INSERT VALUES (ID,Value)
OPTION (MERGE JOIN);
21686765Lock:Acquired8 - IX5 - OBJECT569366358569366358
21686766Lock:Acquired6 - IS5 - OBJECT259897358259897358
21686767Lock:Acquired6 - IS6 - PAGE074220113680591093761:4562
21686768Lock:Acquired3 - S7 - KEY07422011368059109376(8194443284a0)
21686769Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21686770Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21686771Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21686772Lock:Acquired15 - RangeI-N7 - KEY01729461194654482432(8194443284a0)
21686773Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21686774Lock:Released3 - S7 - KEY07422011368059109376(8194443284a0)
21686775Lock:Released6 - IS6 - PAGE074220113680591093761:4562
21686776Lock:Released6 - IS5 - OBJECT259897358259897358
21686777Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21686778Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21686779Lock:Released8 - IX5 - OBJECT569366358569366358
21686838Lock:Acquired8 - IX5 - OBJECT569366358569366358
21686839Lock:Acquired6 - IS5 - OBJECT259897358259897358
21686840Lock:Acquired6 - IS6 - PAGE074220113680591093761:4562
21686841Lock:Acquired3 - S7 - KEY07422011368059109376(8194443284a0)
21686842Lock:Acquired7 - IU6 - PAGE017294611946544824321:2032
21686843Lock:Acquired4 - U7 - KEY01729461194654482432(8194443284a0)
21686844Lock:Acquired8 - IX6 - PAGE017294611946544824321:2032
21686845Lock:Acquired5 - X7 - KEY01729461194654482432(8194443284a0)
21686846Lock:Released0 - NULL7 - KEY01729461194654482432(8194443284a0)
21686847Lock:Released3 - S7 - KEY07422011368059109376(8194443284a0)
21686848Lock:Released6 - IS6 - PAGE074220113680591093761:4562
21686849Lock:Released6 - IS5 - OBJECT259897358259897358
21686850Lock:Released5 - X7 - KEY01729461194654482432(8194443284a0)
21686851Lock:Released8 - IX6 - PAGE017294611946544824321:2032
21686852Lock:Released8 - IX5 - OBJECT569366358569366358
Просто бомба:
1. Баг - со страницы снимается лок, хотя на ней есть ещё залоченная строка
2. Это приводит к тому что будет работать нормально и без хинтов
3. Хватает опять же обычного UpdLock и притом это выгоднее
4. Оказывается локи накладываются не только при обращении к строкам и на границах, но и в других операторах (или Merge-Join или при считывании из других таблиц не owner-ах) что просто открывает непаханое поле деятельности / возможностей организации процессов. Яху. Это же логично! Да-а-а-а!!!

Надо выспаться, перепроверить и переобдумать. Тыкайте если что не так.
13 янв 14, 06:38    [15406005]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
В последнем тесте лишняя строка, которая никак не влияет:
WITH [Source] (ID,Value) AS (SELECT 1,1)


Оператор MERGE локирует (U) конкретные несуществующие строки (не путать с диапазоном), и я никак не могу придумать способ, как это сделать без него.
И вообще это эпично.

Думаю понятно как, или пример дать?
13 янв 14, 17:12    [15409445]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Всё что нашёл на форуме:
4965130
Merge и блокировка
В остальных случаях iljy просто упоминал.
Никакого обсуждения и копания - баг это или в доке явно написано. И хоть каких-то вариантов почему так.
13 янв 14, 21:21    [15410459]     Ответить | Цитировать Сообщить модератору
 Re: Вставка строки  [new]
Михаил1989
Guest
Mnior,

спасибо огромное. щас буду курить инфу и примеры.
13 янв 14, 21:59    [15410559]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить