Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.09.2013, 22:59   #1
Glen
Форумчанин
 
Аватар для Glen
 
Регистрация: 09.02.2011
Сообщений: 150
По умолчанию MS SQL: locking hint для предотвращения вставки?

MS SQL Server 2008

Не могу понять, какой locking hint нужно использовать, чтобы не дать какой-то другой транзакции вставить строку в интересующий меня диапазон строк.

Код примерно такой:


Код:
begin tran

INSERT INTO TargetTable
(WorkCode,WorkNumber)
SELECT Сode, Number
FROM SourceTable
WHERE NOT EXISTS (SELECT 1 FROM TargetTable tt 
                    WHERE tt.WorkCode = Сode 
                        AND tt.WorkNumber = Number)     
commit tran


То есть логика такая: добавлять строку в (WorkCode,WorkNumber) в таблицу TargetTable только если там ещё нет ни одной строки с такой же парой значений (WorkCode,WorkNumber).
Выполняется этот скрипт на уровне изоляции READ COMMITTED SNAPSHOT.
В таблице SourceTable (считаем для простоты) всего одна строка.

Я обнаружил, что если две таких транзакции запустить параллельно, то после COMMIT-а в таблице TargetTable могут оказаться две строки с одинаковой парой значений (WorkCode,WorkNumber)..
Можно предотвратить это, поставив уровень изоляции SERIALIZABLE; но по некоторым причинам мне это неприемлемо. Я хочу добиться результата через locking hint. Но какой?


Причём я не хочу блокировать всю таблицу TargetTable на время вставки. Допустим, я запущу параллельно ещё и такую транзакцию:


Код:
begin tran
INSERT INTO TargetTable
(WorkCode,WorkNumber)
VALUES (123456789, 'A value not equal to the one from SourceTable')
commit tran

то эта последняя транзакция НЕ должна ждать пока не завершатся те первые две. Ведь строка (123456789, 'A value not equal to the one from SourceTable') которую она хочет вставить - НЕ пересекается никак с той строкой из SourceTable.

Я перечитал http://msdn.microsoft.com/en-us/libr...=sql.105).aspx про Table Hints, но так и не понял - что использовать. Потому что не могу применить MSDN к именно моему случаю - "не дать какой-то другой транзакции вставить строку в интересующий нас диапазон строк". Вот например там написано про UPDLOCK:

UPDLOCK
Specifies that update locks are to be taken and held until the transaction completes. UPDLOCK takes update locks for read operations only at the row-level or page-level. If UPDLOCK is combined with TABLOCK, or a table-level lock is taken for some other reason, an exclusive (X) lock will be taken instead.


Не могу понять из этого - он предотвратит вставку НОВЫХ строк в интересующий меня диапазон или нет? То есть если я напишу так:


Код:
INSERT INTO TargetTable
(WorkCode,WorkNumber)
SELECT Сode, Number
FROM SourceTable
WHERE NOT EXISTS (SELECT 1 FROM TargetTable tt 
WITH(UPDLOCK)
                    WHERE tt.WorkCode = Сode 
                        AND tt.WorkNumber = Number)


Это будет то что мне надо?
Glen вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
PasteLink - простой макрос на VBA для Excel для вставки в ячейку гипперссылки на файл в буфере обмена. wyfinger Microsoft Office Excel 4 22.05.2013 14:10
Hint для неактивной кнопки Ivan174 Общие вопросы Delphi 8 25.04.2013 15:11
свойство CheckListBox'а hint (для каждой записи) KORT Общие вопросы Delphi 4 23.01.2013 22:59
Hint для записей DBGrid demiancz БД в Delphi 5 08.09.2011 19:56
Hint для DBLookupListBox RamireZ БД в Delphi 0 23.06.2010 23:12