powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
8 сообщений из 8, страница 1 из 1
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
    #40049483
RuCosinus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.

Вопрос довольно детский, как я предполагаю, но ответа не нашел.

Вводные:
- есть процедура procname, которая дергается по job раз в час, результатом работы - обновление определенных значений в постоянной таблице tablename . Пояснение - это таблица некий кэш, решено было пожертвовать некоторой актуальностью в пользу быстродействия, потому что к запросу этих параметров предполагается много обращений и альтернативой выступает только расчет значений при каждом обращении, что очень тяжко. Данные обновляются для ID объектов, которые мы получаем выборкой в начале procname

То есть примерно вот так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
ALTER TABLE procname
begin
	--Создаем временную таблицу
	IF OBJECT_ID(N'tempdb.dbo.#pData',N'U') IS NOT NULL
		   DROP table dbo.#pData
	create table #pData
	(
	ID numeric(15, 0) NOT NULL, PRIMARY KEY NONCLUSTERED (ID)
	,par_1 numeric(15,2)
	,par_2 numeric(15,2)
	,par_3 numeric(15,2)
	)
	--Заполняем ID
	insert into #pData
	(ID)
	select distinct ID
	from tb1 t1
	inner join tb2 t2 on...
	...
	
	--Получаем параметры par_1, par_2 и par_3 для этих ID
	/*
	Здесь много разного кода
	*/

	--Обновляем данные в таблице tablename
	
end



Так как полученные в результате запроса ID могут отличаться из часа в час, то обновлять, по идее, получается можно двумя способами:
1) тремя инструкциями в подряд, а именно:
- удаляем из постоянной таблицы tablename строки с ID, которые есть в tablename , но отсутствуют в #pData
- обновляем значения для ID, которые есть в постоянной таблице tablename и присутствуют в #pData
- добавляем в постоянную таблицу строки с ID, которых нет в tablename , но есть в #pData
2) двумя инструкциями:
- удалить все из постоянной таблицы tablename
- добавить в постоянную таблицу tablename все записи из #pData

Сам вопрос:
возможно ли повесить блокировку на постоянную таблицу tablename во время выполнения всех инструкций в подряд? Потому что при обоих вариантах существует вероятность, что запрос на чтение к постоянной таблице прилетит до выполнения всего блока инструкций, т.е. , например, во втором случае после delete, но до insert. Может как-то транзакцией можно разрулить?
Как в общем виде решаются такие задачи?
...
Рейтинг: 0 / 0
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
    #40049486
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RuCosinus,

селект с хинтами tablockx, serializable перед обновлениями вашей таблицы.
...
Рейтинг: 0 / 0
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
    #40049494
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RuCosinus,

3) одной инструкцией merge
...
Рейтинг: 0 / 0
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
    #40049495
RuCosinus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сон Веры Павловны
RuCosinus,
селект с хинтами tablockx, serializable перед обновлениями вашей таблицы.


Ага, то есть меняем вот так:
Код: sql
1.
2.
3.
4.
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
--Обновляем данные в таблице tablename (все инструкции)
COMMIT TRANSACTION



А в процедуре, где происходит выборка из таблицы tablename , ставим хинт WITH (TABLOCKX)

SERIALIZABLE запрещает нам читать неподтвержденные данные до окончания транзакции, а TABLOCKX ставит монопольную блокировку на таблицу. Но я не совсем понимаю, зачем тут TABLOCKX . Запросы на чтение идут из других транзакций и вроде как пока я не выполню транзакцию с уровнем изоляции SERIALIZABLE они и так не получат данные. В чем я не прав?
...
Рейтинг: 0 / 0
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
    #40049499
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RuCosinus,

Неправильно понимаете.
Serializable будет удерживать [u]ваши блокировки[u] до окончания вашей транзакции.

А tablockx получит монопольную блокировку на всю таблицу сразу а не на строки/страницы
...
Рейтинг: 0 / 0
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
    #40049506
RuCosinus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
felix_ff
RuCosinus,
Неправильно понимаете

Понял, спасибо за разъяснения

felix_ff
RuCosinus,
3) одной инструкцией merge

Совсем и забыл про merge, спасибо за альтернативу
...
Рейтинг: 0 / 0
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
    #40050508
Gerros
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RuCosinus,

merge без tablockx не гарантирует что никто не прочитает данные в промежуточном состоянии.

Самый простой код - вот так:
Код: sql
1.
2.
3.
4.
begin tran
truncate table tablename
insert tablename select * from #pData
commit


truncate заблокирует метаданные до конца транзакции - никто не сможет читать\писать.

Самое быстрое переключение наверное будет при переключении секций.
...
Рейтинг: 0 / 0
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
    #40050512
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gerros,
- удалить все из постоянной таблицы tablename
- добавить в постоянную таблицу tablename все записи из #pData

Это реализуется создание второй такой же таблицы и переключением секции alter table ... switch partition. Произойдет быстрая замена старых данных на новые. Выше предлагали этот способ.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]