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

Откуда:
Сообщений: 49
Есть таблица, в нее постоянно происходят инсёрты. Мне нужно раз в N минут делать из нее селект (выбираются не все записи) и вставлять в другую таблицу. После чего удалять (или помечать) все записи, которые были в ней к моменту начала селекта, чтобы через N минут они уже не мешались. При этом нужно не мешать другому процессу продолжать в нее инсертить. Как это можно сделать? Спасибо.
7 фев 14, 00:12    [15531711]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки? Транзакции?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31868
forrfor
Как это можно сделать?
Нужно сделать "таблицу удалённых", вставлять туда одним запросом, потом в цикле мелкими порциями в мелких транзакциях вставлять в нужную таблицу и удалять из этой промежуточной.
Тогда, даже если будет падение на любом этапе, целостность не нарушится, и другим пользователям мешать не будете.
7 фев 14, 00:33    [15531752]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки? Транзакции?  [new]
forrfor
Member

Откуда:
Сообщений: 49
alexeyvg
forrfor
Как это можно сделать?
Нужно сделать "таблицу удалённых", вставлять туда одним запросом, потом в цикле мелкими порциями в мелких транзакциях вставлять в нужную таблицу и удалять из этой промежуточной.
Тогда, даже если будет падение на любом этапе, целостность не нарушится, и другим пользователям мешать не будете.


Вы предлагаете вместо одного переноса из таблицы в таблицу делать два последовательно? Теперь у меня две проблемы вместо одной.. )
Объясните поподробнее, пожалуйста.
7 фев 14, 00:52    [15531788]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки? Транзакции?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31868
forrfor
Вы предлагаете вместо одного переноса из таблицы в таблицу делать два последовательно? Теперь у меня две проблемы вместо одной.. )
Объясните поподробнее, пожалуйста.
Тогда расскажите, какая собственно проблема.
forrfor
При этом нужно не мешать другому процессу продолжать в нее инсертить
В моём способе другому процессу будет мешать только шаред-блокировка при чтении записей, это обычно недолго и не так критично.
А удаления и вставки будут в мелких транзакциях, мешат никому не будут.

Или у вас вообще речь о небольших блоках данных?
Тогда вообще непонятно, в чём вопрос. Открываете транзакцию, читаете данные, вставляете в джругую таблицу, удаляете из источника. Это, к примеру, займёт десяток миллисекунд для небольшого количества записей.
7 фев 14, 09:30    [15532527]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки? Транзакции?  [new]
Jaffar
Member

Откуда:
Сообщений: 633
forrfor,

Можно запомнить Min и MAX ID из таблицы источника в переменные.

потом по ним выбрать данные в другую таблицу,
потом по ним удалить или пометить строки в 1 таблице как обработанные


select @Min = min(ID), @Max = max(ID) from Table1

insert Table2(....)
select ...
from Table1
where
        ID between @Main and @Max
        
delete from Table2 where ID between @Main and @Max
7 фев 14, 10:02    [15532617]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки? Транзакции?  [new]
Glory
Member

Откуда:
Сообщений: 104751
forrfor
Мне нужно раз в N минут делать из нее селект (выбираются не все записи) и вставлять в другую таблицу. После чего удалять (или помечать) все записи, которые были в ней к моменту начала селекта, чтобы через N минут они уже не мешались.

DELETE/UPDATE tab1 ... OUTPUT INTO tab2 ...
7 фев 14, 10:14    [15532682]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки? Транзакции?  [new]
forrfor
Member

Откуда:
Сообщений: 49
Jaffar
forrfor,

Можно запомнить Min и MAX ID из таблицы источника в переменные.

потом по ним выбрать данные в другую таблицу,
потом по ним удалить или пометить строки в 1 таблице как обработанные


select @Min = min(ID), @Max = max(ID) from Table1

insert Table2(....)
select ...
from Table1
where
        ID between @Main and @Max
        
delete from Table2 where ID between @Main and @Max


Спасибо, очень понравилось решение!
7 фев 14, 19:32    [15536653]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки? Транзакции?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31868
forrfor
Jaffar
forrfor,

Можно запомнить Min и MAX ID из таблицы источника в переменные.

потом по ним выбрать данные в другую таблицу,
потом по ним удалить или пометить строки в 1 таблице как обработанные


Спасибо, очень понравилось решение!
А мне не понравилось. Если кто то вставит записи после запоминания Min и MAX ID, то будут трудноопределяемые ошибки. Хотя при определённых условиях оно работать будет, но зачем писать только для этих условий, если столько же труда можно затратить на правильное решение?

Лучше использовать решение Glory, оно гарантирует правильный результат при любых настройках сервера, алгоритмах приложения, любой работе с сервером.
7 фев 14, 19:37    [15536680]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить