Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
ASQLUser
Guest |
Вопрос такой. Имеется таблица из двух полей: create table t ( t_id int, num int) Также имеется диапазон значений num : 1 .. 10000 В таблице t_id уникальны, num из указанного диапазона. Задача в следующем. Есть хранимая процедура. На входе в нее передается параметр @t_id. Нужно найти минимальную свободную (т.е. не содержится в таблице) позицию из диапазона и записать в таблицу (@t_id, эта позиция). Процедуру одновременно вызывают из большого числа соединений, не должны записываться и возвращаться одинаковые значения для них. |
16 янв 17, 17:46 [20111408] Ответить | Цитировать Сообщить модератору |
Гавриленко Сергей Алексеевич Member Откуда: Moscow Сообщений: 37202 |
Завести таблицу с записями 1...10000, после чего выбирать из нее первую запись, которой нет в t. |
16 янв 17, 17:50 [20111433] Ответить | Цитировать Сообщить модератору |
ASQLUser
Guest |
Гавриленко Сергей Алексеевич, Такая таблица есть ), проблема не в этом. Два параллельных запроса выбирают одну и ту же запись. Первый запрос уже выбрал запись, но не успел еще ее записать, второй выбирает ту же самую. |
16 янв 17, 18:00 [20111471] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6802 |
ASQLUser, переходите к изучению уровней изоляции |
16 янв 17, 18:02 [20111484] Ответить | Цитировать Сообщить модератору |
Руслан Дамирович Member Откуда: Резиновая нерезиновая Сообщений: 942 |
Значит, нужно еще поле, куда писать количество считываний и ограничение на "непорочный" счетчик чтений... и тут вопрос, а какова цель этого циркового представления? |
16 янв 17, 18:03 [20111486] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6802 |
что??? |
||
16 янв 17, 18:04 [20111489] Ответить | Цитировать Сообщить модератору |
Руслан Дамирович Member Откуда: Резиновая нерезиновая Сообщений: 942 |
А где сказано, что что-то там со счетчиком будет происходить в одной транзакции? Додумывать за автором сейчас вообще не пойми какой костыль - ишь, транзЪкция окаянныя! Да вы, батенька, салатиков на новый год переели :) |
||||
16 янв 17, 18:06 [20111493] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6802 |
как забыть оба ваши комментария... |
||||
16 янв 17, 18:09 [20111508] Ответить | Цитировать Сообщить модератору |
ASQLUser
Guest |
Ценю Ваш совет, Вы открыли мне глаза. По делу сказать что-то можете? |
||
16 янв 17, 18:18 [20111536] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6802 |
ленивые все стали.... SET TRANSACTION ISOLATION LEVEL READ COMMITED/SERIALIZABLE BEGIN TRAN выбрали вставили COMMIT |
||||
16 янв 17, 18:20 [20111546] Ответить | Цитировать Сообщить модератору |
ASQLUser
Guest |
С полями идеи не понял. Цель вполне прозаическая, трюками не занимаюсь. Упростил задачу, убрав бизнес-логику. К SQL она отношения не имеет. |
||
16 янв 17, 18:22 [20111554] Ответить | Цитировать Сообщить модератору |
ASQLUser
Guest |
SERIALIZABLE - жестоко, вылезают дедлоки. READ COMMITED не мешает захватывать дубли, блокировка не висит постоянно внутри транзакции. |
||||
16 янв 17, 18:42 [20111613] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6802 |
танунафиг... создавайте поля |
||||
16 янв 17, 18:44 [20111618] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
create table t ( t_id int, num int identity(1, 1)) И не фантазируйте - все придумано до вас. ЗЫ. Тока не говорите, что вам еще и удалять надо. |
||
16 янв 17, 20:36 [20112000] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9688 |
update t set num = a.num from dbo.t t cross apply (select top (1) num from Диапазон d with (updlock, readpast) where not exists(select 1 from dbo.t where num = d.num order by d.num) a where t.t_id = @t_id;Плюс уникальный индекс Диапазон (num) и уникальный фильтрованный индекс t (num) where num is not null. |
16 янв 17, 21:43 [20112202] Ответить | Цитировать Сообщить модератору |
ASQLUser
Guest |
Как Вы думаете, зачем я так подробно описал задачу? Да, нужно удалять, да identity не подходит. |
||
17 янв 17, 10:37 [20113295] Ответить | Цитировать Сообщить модератору |
ASQLUser
Guest |
Идея понятна, а почему order by во вложенном подзапросе? Фильтрованный индекс по t(num) должен быть с полным покрытием полей в t или это не обязательно? Жалко, что "из коробки" решение не подходит (уникальный индекс Диапазон (num) создать нельзя), но попробую допилить напильником ) |
||
17 янв 17, 13:59 [20114269] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9688 |
Без такого индекса запрос может ничего не найти, хотя на самом деле подходящие данные будут. ЗЫ: Возможно индексы придется указывать принудительно хинтами. План запроса покажет нужно ли это. |
||||||
17 янв 17, 14:17 [20114335] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6802 |
invm,
|
||
17 янв 17, 14:23 [20114360] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9688 |
|
||
17 янв 17, 14:36 [20114432] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
Это у вас плохо с воображением. Любая задача может быть решена двумя путями: а) просто. б) через жопу. Пока ваш путь б). |
||||
17 янв 17, 15:21 [20114736] Ответить | Цитировать Сообщить модератору |
ASQLUser
Guest |
С первыми двумя понятно: в первом смутила скобка, так и подумал, что просто ошибка, но решил уточнить. со вторым понятно, уточнил на всякий случай. В третьем да, может получиться tablock и readpast ничего не найдет. Сделать без readpast? |
||||
17 янв 17, 18:05 [20115615] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6802 |
ну да, с учётом того что весь запрос построен на использовании READPAST сделайте без него |
||||
17 янв 17, 18:07 [20115627] Ответить | Цитировать Сообщить модератору |
ASQLUser
Guest |
Запрос не построен на READPAST, хотя это эффективный способ обойти лишние блокировки. И еще. По идее rowlock блокирует даже при неуникальном индексе, но требуется покрытие индексом выбираемых столбцов. |
||||
17 янв 17, 18:20 [20115668] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6802 |
это просто клиника |
||||
17 янв 17, 18:21 [20115671] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Все форумы / Microsoft SQL Server | ![]() |