|
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
|
|||
---|---|---|---|
#18+
Добрый день. Вопрос довольно детский, как я предполагаю, но ответа не нашел. Вводные: - есть процедура 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.
Так как полученные в результате запроса ID могут отличаться из часа в час, то обновлять, по идее, получается можно двумя способами: 1) тремя инструкциями в подряд, а именно: - удаляем из постоянной таблицы tablename строки с ID, которые есть в tablename , но отсутствуют в #pData - обновляем значения для ID, которые есть в постоянной таблице tablename и присутствуют в #pData - добавляем в постоянную таблицу строки с ID, которых нет в tablename , но есть в #pData 2) двумя инструкциями: - удалить все из постоянной таблицы tablename - добавить в постоянную таблицу tablename все записи из #pData Сам вопрос: возможно ли повесить блокировку на постоянную таблицу tablename во время выполнения всех инструкций в подряд? Потому что при обоих вариантах существует вероятность, что запрос на чтение к постоянной таблице прилетит до выполнения всего блока инструкций, т.е. , например, во втором случае после delete, но до insert. Может как-то транзакцией можно разрулить? Как в общем виде решаются такие задачи? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.03.2021, 11:16 |
|
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
|
|||
---|---|---|---|
#18+
RuCosinus, селект с хинтами tablockx, serializable перед обновлениями вашей таблицы. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.03.2021, 11:23 |
|
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
|
|||
---|---|---|---|
#18+
RuCosinus, 3) одной инструкцией merge ... |
|||
:
Нравится:
Не нравится:
|
|||
01.03.2021, 11:45 |
|
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
|
|||
---|---|---|---|
#18+
Сон Веры Павловны RuCosinus, селект с хинтами tablockx, serializable перед обновлениями вашей таблицы. Ага, то есть меняем вот так: Код: sql 1. 2. 3. 4.
А в процедуре, где происходит выборка из таблицы tablename , ставим хинт WITH (TABLOCKX) SERIALIZABLE запрещает нам читать неподтвержденные данные до окончания транзакции, а TABLOCKX ставит монопольную блокировку на таблицу. Но я не совсем понимаю, зачем тут TABLOCKX . Запросы на чтение идут из других транзакций и вроде как пока я не выполню транзакцию с уровнем изоляции SERIALIZABLE они и так не получат данные. В чем я не прав? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.03.2021, 11:53 |
|
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
|
|||
---|---|---|---|
#18+
RuCosinus, Неправильно понимаете. Serializable будет удерживать [u]ваши блокировки[u] до окончания вашей транзакции. А tablockx получит монопольную блокировку на всю таблицу сразу а не на строки/страницы ... |
|||
:
Нравится:
Не нравится:
|
|||
01.03.2021, 11:59 |
|
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
|
|||
---|---|---|---|
#18+
felix_ff RuCosinus, Неправильно понимаете Понял, спасибо за разъяснения felix_ff RuCosinus, 3) одной инструкцией merge Совсем и забыл про merge, спасибо за альтернативу ... |
|||
:
Нравится:
Не нравится:
|
|||
01.03.2021, 12:22 |
|
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
|
|||
---|---|---|---|
#18+
RuCosinus, merge без tablockx не гарантирует что никто не прочитает данные в промежуточном состоянии. Самый простой код - вот так: Код: sql 1. 2. 3. 4.
truncate заблокирует метаданные до конца транзакции - никто не сможет читать\писать. Самое быстрое переключение наверное будет при переключении секций. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.03.2021, 01:50 |
|
Возможно ли поставить блокировку на таблицу во время выполнения нескольких инструкций
|
|||
---|---|---|---|
#18+
Gerros, - удалить все из постоянной таблицы tablename - добавить в постоянную таблицу tablename все записи из #pData Это реализуется создание второй такой же таблицы и переключением секции alter table ... switch partition. Произойдет быстрая замена старых данных на новые. Выше предлагали этот способ. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.03.2021, 02:38 |
|
|
start [/forum/topic.php?fid=46&fpage=32&tid=1685013]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
44ms |
get tp. blocked users: |
2ms |
others: | 13ms |
total: | 135ms |
0 / 0 |