|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
Всем добрый день. Есть следующая схема работы процесса: Есть большая таблица (несколько миллионов записей), в которую постоянно добавляются новые записи на обработку. Есть несколько программ-обработчиков поступающих записей. Для выбора новых транзакций используется хранимка в которой следующий подход: 1. на вход хранимки поступает уникальный идентификатор приложения AppID и номер пакета обработки Q (он уникальный в пределах 2. делаем запрос в базу: обнови N необработанных записей (любых) - поставь им номер очереди Q и обработчик app_id update myRecords set Sequence=@Q, AppID=@AppID where Sequence=-1 and AppID=' ' 3. выбираем все записи с Q и app_id - они отравляются на обработчик и вот на этапе 2 у нас часто происходит дедлок как можно этого избежать? в пункте 2 нам неважно какие именно необработанные записи выберутся самое главное условие - чтоб разные обработчики не смогли выбрать одну и ту же запись P.s. Sybase ASE 15.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 15:17 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
условие where Sequence=-1 and AppID=' ' явно не достаточно для логического разделения записей, оттого и дедлок между добавляющими и обновляющим процессом. Попробуйте в этут таблицу добавить поле со временем добавления записи, а в обновляющем процессе использовать его в условии поиска where Sequence=-1 and AppID=' ' and tran_date between .... А в обновляющем хранить эти интервалы. Тогда не будет таких явных конфликтов и конкуренции. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 17:14 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
cheese.dp, Один делает (А,Б) - другой (Б, А). Избежать просто - пределить однозначный порядок обновлений. (Типа всегда А,Б) ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 18:07 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
в принципе поле с датой попадания записи в таблицу есть при insert оно устанавливается в getdate() вы предлагаете его использовать? ... where Sequence=-1 and AppID=' ' and date between dateadd(day,-1, getdate()) and getdate() так? и это сможет помочь? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 18:07 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
mikroncheese.dp, Один делает (А,Б) - другой (Б, А). Избежать просто - пределить однозначный порядок обновлений. (Типа всегда А,Б) обработчиков несколько, их не 2 - и их количество может меняться и вся система должна работать при прекращении работы обработчиков, типа один из десяти упал - ничего, работаем дальше ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 18:09 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
Если я правильно понимаю, то после апдейта должен идти комит. Если так, то можно подумать на счёт "dirty read" для транзакции. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 18:14 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
cheese.dpобработчиков несколько, их не 2 - и их количество может меняться и вся система должна работать при прекращении работы обработчиков, типа один из десяти упал - ничего, работаем дальше А я и не про обработчики, а про data rows и порядок их локировки. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 18:16 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
mikronЕсли я правильно понимаю, то после апдейта должен идти комит. Если так, то можно подумать на счёт "dirty read" для транзакции. поясните плиз... ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 18:22 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
mikronА я и не про обработчики, а про data rows и порядок их локировки. можно подробнее про этот момент? где почитать? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 18:23 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
чиз, у вас два варианта, либо поняв те идеи, что вам накидали применить их в своей задаче, адаптировав под конкретные ваши условия, либо показывать схему таблицы, что и как обрабатывается, т.е. дать решать задачу нам, вместо вас. Лучше конечно же самому.. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 18:46 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
cheese.dpmikronЕсли я правильно понимаю, то после апдейта должен идти комит. Если так, то можно подумать на счёт "dirty read" для транзакции. поясните плиз... Я бы попробывал так: 1. поставить уровень изоляции read uncommitted 2. Выполнить обновление как было описано и закрепить транзакцию. 3. Вернуть уровень изоляции 4. Совершить чтение как было писано вами ранее. Походу возник интересный вопрос: что произойдёт если транзакция выполнит коммит раньше чем поставьщик данных (тот, кто делает инсерт) и что будет с поставщиком при коммите/роллбэке? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 23:08 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
mikroncheese.dpпропущено... поясните плиз... Я бы попробывал так: 1. поставить уровень изоляции read uncommitted 2. Выполнить обновление как было описано и закрепить транзакцию. 3. Вернуть уровень изоляции 4. Совершить чтение как было писано вами ранее. Походу возник интересный вопрос: что произойдёт если транзакция выполнит коммит раньше чем поставьщик данных (тот, кто делает инсерт) и что будет с поставщиком при коммите/роллбэке? Я не прав. Глупая идея. Не пробуйте так, так ничего не будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2012, 23:18 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
Ggg_oldчиз, у вас два варианта, либо поняв те идеи, что вам накидали применить их в своей задаче, адаптировав под конкретные ваши условия, либо показывать схему таблицы, что и как обрабатывается, т.е. дать решать задачу нам, вместо вас. Лучше конечно же самому.. да тут-то и показывать особо нечего основной момент - то, что в таблицу попадают данные от внешних систем с большой частотой (эту часть никак нельзя менять) мне лишь нужно максимально быстро выбрать записи, и обработать их ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2012, 09:35 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
ну тогда привязывайтесь ко времени в обработчике, как я предложил. Только тут важно, что-бы процесс, который назначает номер Q задания для обработчиков был один. Иначе будет та же конкуренция и дедлоки. Итого выходит так: - много писателей, которые пишут события. В событии присутствует время поступения. Вот последнее время поступления еще постоянно отражается в вспомогательной табличке. - Один процесс, который назначает номера на обработку читает из вспомогательных таблиц время своего предыдущего запуска и время последнего добавленного события. Вспомогательные таблицы нужны, что-бы не делать select max() from таблица_событий. Если сервер азе или SA в режиме блокировчника, то таблицу с временем последней добавленной транзакции можно читать в режиме dirty read, т.к. добавляющие процессы будут конкурировать за эту таблицу. - Все записи с интервалом временем между предыдущим стартом и считанным текущим временем апдейтим как вам надо. - фиксируем новый интервал времени как время предыдущего запуска скрипта. Нужны соответственно индексы по полю времени. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2012, 10:34 |
|
одневременный update и deadlock
|
|||
---|---|---|---|
#18+
cheese.dp, readpast http://manuals.sybase.com/onlinebooks/group-as/asg1250e/sqlug/@Generic__BookTextView/55770;pt=55490 ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2012, 12:50 |
|
|
start [/forum/topic.php?fid=55&gotonew=1&tid=2010118]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
152ms |
get topic data: |
12ms |
get first new msg: |
8ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 276ms |
0 / 0 |