|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
Вопрос к умным людям, то фантазия закончилась к пятнице. Есть таблица в нее делается вставка данных, перед вставкой проверяется существует ли уже такая запись. Примерная структура: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Суть в том что у нас в SessionEntiry может быть несколько одинаковых EntiryID Н-потоков начинают из таблицы выгребать свою порцию KeyID по принципу KeyID % @Divisor = @Modulo И потом Н-потоков могут одновременно выполнить IF NOT EXISTS в рамках одного @EntiryID и так возникает конфликтная ситуация. Структура таблицы и логика меняться не будет, поэтому вот думаю как лучше сделать EXISTS. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 15:10 |
|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
1. Уникальный индекс на EntiryID. 2. Тупо вставлять и обрабатывать ошибку. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 15:22 |
|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
Если "в лоб", то Код: sql 1.
Соответсвенно, нужен индекс по EntiryID ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 15:29 |
|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
Структуру никто менять не будет. Уникальный индекс тоже нет возможности добавить. Если еще проще выразиться, то в момент когда одновременно в одном потоке происходит: Код: sql 1.
В другом потоке уже должно корректно понимать что: Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 15:29 |
|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
aleks222 1. Уникальный индекс на EntiryID. Sergey Syrovatchenko в SessionEntiry может быть несколько одинаковых EntiryID Sergey Syrovatchenko, Правильно ли я понимаю, что вам нужно позволять вставлять данные в dbo.SessionEntiry только если будущий KeyID % @Divisor для EntiryID еще не существует в таблице? Т.к. определить значение identity до вставки нельзя, проверяйте после и удаляйте ненужные записи. Это если совсем ничего в структуре данных менять нельзя. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 15:32 |
|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
Либо другой вариант, когда Н-потоков одновременно делают проверку на Код: sql 1.
Первый кто успел вставил, а уже другие фактически будут вставлять дубликаты. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 15:33 |
|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
Sergey Syrovatchenko, Чтобы исключить вставку дубликатов ваши exists нужно выстраивать в очередь. Один из способов я уже показал. Более щадящий - эксклюзивный applock уровня транзакции на основе значения @EntiryID А вообще подобное делается через merge. Но все равно для гарантии исключения возникновения дубликатов придется включать serializable для целевой таблицы. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 15:41 |
|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
Ну и еще вариант - уникальный индекс по EntiryID с IGNORE_DUP_KEY Данные вставлять, если @@rowcount = 0, то апдейтить. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 16:32 |
|
Параллельный доступ к таблице в EXISTS
|
|||
---|---|---|---|
#18+
Да, без очереди никак. Но будет узкое горло. Лучшее решение - уникальный индекс с игнором дубликатов ключей. Если N потоков не захотят ждать, то организуйте очередь ServiceBroker с последовательной обработкой одного запроса за одним. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 16:50 |
|
|
start [/forum/topic.php?fid=46&msg=39955356&tid=1686153]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
31ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
others: | 17ms |
total: | 146ms |
0 / 0 |