|
|
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
hi all. Возник вопрос по регистрам оборотов и остатков, показанных в теме "Шаблон. Ресурсы накопления ". У нас есть нечто похожее на это, применяется для учета остатков изделий. Таблица BalanceTable, обновляемая триггером TurnoverTable.OnAfterDelete, при интенсивном вводе данных становится узким местом. На её строках будут постоянно возникать конфликты обновления со стороны разных сеансов. Возникла мысль добавить в эту таблицу дополнительное измерение, связанное с номером коннекта (connect_id). В течение дня в эту таблицу будет выполняться merge с учетом этого connect_id. Чтобы кол-во записей не разрасталось, ночью можно запускать job, "схлопывающий" остатки, т.е. группирующий их без учета connect_id и удаляющий в случае успеха строки с conn_id is not null. Понятно, что получения текущего остатка от суммирования никуда не деться - такова плата за уход от блокировок. Непонятно, однако, как в таком случае проконтролировать неотрицательность остатков ? Суммировать "по коннектам" стр о ки в триггере - бесполезно, триггер не видит чужих не зафиксированных изменений. Что посоветуете ? ЗЫ. модераторам : прошу не переносить (пока) в раздел "Проектирование", хочу сначала послушать односельчан :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 09:08 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Даже если такой таблицы не будет, вычисления остатков будут делаться "на лету", то блокировать данные придется весь вопрос какие, оптимально конечно блокировать в таблицах те данные, которые будут меняться данной транзакцией, то есть строки по определенным наборам измерений (товаров, складов и проч.) Если СУБД позволяет блокировать так, то это хорошо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 10:21 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
ТаблоидТаблица BalanceTable, обновляемая триггером TurnoverTable.OnAfterDelete, при интенсивном вводе данных становится узким местом. На её строках будут постоянно возникать конфликты обновления со стороны разных сеансов.Странно, что такая простая операция становится узким местом. ТаблоидПонятно, что получения текущего остатка от суммирования никуда не деться - такова плата за уход от блокировок. Непонятно, однако, как в таком случае проконтролировать неотрицательность остатков ?Вы же, раз отказываетесь от хранения баланса, то должны будете считать баланс на лету. Тут всё просто - блокируете TurnoverTable и считаете, и никаких отрицательных остатков. Только блокировка получится больше, чем для расчёта баланса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 10:36 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
alexeyvgТаблоидТаблица BalanceTable, обновляемая триггером TurnoverTable.OnAfterDelete, при интенсивном вводе данных становится узким местом. На её строках будут постоянно возникать конфликты обновления со стороны разных сеансов.Странно, что такая простая операция становится узким местом.Операция-то простая (вставка в документ энного количества), да делают её десятки человек сразу. И если востребовано одно и то же изделие, неизбежно возникнут драки за ресурс. alexeyvgТут всё просто - блокируете TurnoverTable и считаете, и никаких отрицательных остатков.вы про блокировку всей таблицы ? ну так это еще хуже, чем сейчас. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 13:13 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Nafоптимально конечно блокировать в таблицах те данные, которые будут меняться данной транзакцией, то есть строки по определенным наборам измерений (товаров, складов и проч.) Если СУБД позволяет блокировать так, то это хорошоИзначально я и говорил про блокировку отдельных строк . Блокировку всей таблицы даже не рассматриваю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 13:15 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
ТаблоидalexeyvgСтранно, что такая простая операция становится узким местом.Операция-то простая (вставка в документ энного количества), да делают её десятки человек сразу. И если востребовано одно и то же изделие, неизбежно возникнут драки за ресурс.Ну не знаю... Операция не должна занимать больше милисекунды, значит, до 1000 запросов на ядро. Если пользователи редактирует документы по минуте, то это операция не доставит проблем 240 000 одновременно работающим пользователям для 4-х ядерного проца. В противном случае у вас неоптимальный код :-) Я немного утрирую, конечно, но реально вставка/обновление записи ничто по сравнению с другими операциями, которые делаются для этой бизнес-операции. ТаблоидalexeyvgТут всё просто - блокируете TurnoverTable и считаете, и никаких отрицательных остатков.вы про блокировку всей таблицы ? ну так это еще хуже, чем сейчас.Нет, не всей таблицы, а только для данных, по которым делается пересчёт. Но конечено, т.к. пересчёт делается по актуальным данным, то этот метод будет более "блокирующим". Собственно, таблицы остатков и придумали, чтобы уменьшить нагрузку и блокировки, а не наоборот :-) Не любят его только из-за возможных проблем с целостностью, корректностью данных. А так-то он самый оптимальный, лучьше не придумаете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 14:07 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
ТаблоидNafоптимально конечно блокировать в таблицах те данные, которые будут меняться данной транзакцией, то есть строки по определенным наборам измерений (товаров, складов и проч.) Если СУБД позволяет блокировать так, то это хорошоИзначально я и говорил про блокировку отдельных строк . Блокировку всей таблицы даже не рассматриваю. Я не понял, у вас проблема с бликировками, или с мертвыми блокировками? Если с мертвыми - переписывайте запросы. Если с просто блокировками - то тут есть варианты: 1. Возможно у вас просто не хватает индексов, поэтому блокируются лишние записи. 2. Возможно вы нарываетесь на эскалацию блокировок, тогда можно попробовать ее отключить. Но это может и ухудшить ситуацию, потому что на строчные блокировки пойдет больше ресурсов. 3. Опять же - возможно у вас неоптимальные запросы или завышеный TIL. И кстати - что за СУБД? На MSSQL я бы посоветовал глянуть в сторону RCSI. 4. Ну и наконец - можно попробовать организовать асинхронное обновление тем или иным способом. Для этого можно использовать Service Broker или аналог, либо таблицы с ИД измененных-добавленных записей + задание, выполняющее пересчет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 14:16 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
alexeyvgТаблоидпропущено... Операция-то простая (вставка в документ энного количества), да делают её десятки человек сразу. И если востребовано одно и то же изделие, неизбежно возникнут драки за ресурс. Если пользователи редактирует документы по минуте , то это операция не доставит проблем 240 000 одновременно работающим пользователям для 4-х ядерного проца.Нет, конечно :-) У нас ни у кого из юзеров нет "бесконтрольной блокировки" на строке (т.е. нет такого что он заблокировал строку и ушёл на обед). Но они при работе с клиентами обращаются к двум регистрам (упрощенно): "доступно на складе" и "зарезервировано под клиента". Время переноса количества между регистрами (по заранее выбранному изделию) минимальное, действительно там несколько ms. Но вот клиент приезжает и ему надо расплачиваться за товар. Документ, все его NNN строк, должен быть ЦЕЛИКОМ переведен из статуса "Зарезервировано" в статус "Отгружено". Перевод документа в другой статус - это не только движуха по двум регистрам каждой его строки. Как минимум там еще надо FIFO-цепочки выстроить по приходам, с которых "сдёргивается" каждая строка этого расхода. Еще надо обновить баланс и обороты контрагента, записать инфу в аудит, да много чего еще надо. Я это к тому, что если в документе 300 строк, то эта операция уже не будет занимать миллисекунды - тут речь идет уже о нескольких секундах. И блокировки начинаются именно из-за этого: кладовщик Вася хочет зарезервировать изделие_Х, а оно состоит каком-то другом в документе, который содержит 100500 строк и сейчас переводится в статус "Отгружено". А еще чаще сталкиваются лбами два кассира, закрывающие документы с "пересекающимися" по номенклатуре позициями. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 15:07 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
iljyТаблоидпропущено... Изначально я и говорил про блокировку отдельных строк . Блокировку всей таблицы даже не рассматриваю. Я не понял, у вас проблема с бликировками, или с мертвыми блокировками? Если с мертвыми - переписывайте запросы. Если с просто блокировками - то тут есть варианты: 1. Возможно у вас просто не хватает индексов, поэтому блокируются лишние записи. 2. Возможно вы нарываетесь на эскалацию блокировок, тогда можно попробовать ее отключить. Но это может и ухудшить ситуацию, потому что на строчные блокировки пойдет больше ресурсов. 3. Опять же - возможно у вас неоптимальные запросы или завышеный TIL. И кстати - что за СУБД? На MSSQL я бы посоветовал глянуть в сторону RCSI. 4. Ну и наконец - можно попробовать организовать асинхронное обновление тем или иным способом. Для этого можно использовать Service Broker или аналог, либо таблицы с ИД измененных-добавленных записей + задание, выполняющее пересчет.У нас трабл с "просто" блокировками (НЕ мертвыми). Я работаю с Firebird 2.5. Даже при отсутствии индексов он никогда делает эскалацию блокировки: пытается заблокировать только то, что нужно по where-предикату. TIL минимальный - read write read committed. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 15:11 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
alexeyvgСобственно, таблицы остатков и придумали, чтобы уменьшить нагрузку и блокировки, а не наоборот :-) Да, для СУБД в которых select-ы создают блокировки. Таковых, к счастью, теперь практически не осталось. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 15:21 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Таблоидalexeyvg Если пользователи редактирует документы по минуте , то это операция не доставит проблем 240 000 одновременно работающим пользователям для 4-х ядерного проца.Нет, конечно :-) У нас ни у кого из юзеров нет "бесконтрольной блокировки" на строке (т.е. нет такого что он заблокировал строку и ушёл на обед).Я имел в виду, если каждый пользователь создаёт в среднем один документ в минуту. ТаблоидВремя переноса количества между регистрами (по заранее выбранному изделию) минимальное, действительно там несколько ms. Но вот клиент приезжает и ему надо расплачиваться за товар. Документ, все его NNN строк, должен быть ЦЕЛИКОМ переведен из статуса "Зарезервировано" в статус "Отгружено". Перевод документа в другой статус - это не только движуха по двум регистрам каждой его строки. Как минимум там еще надо FIFO-цепочки выстроить по приходам, с которых "сдёргивается" каждая строка этого расхода. Еще надо обновить баланс и обороты контрагента, записать инфу в аудит, да много чего еще надо. Я это к тому, что если в документе 300 строк, то эта операция уже не будет занимать миллисекунды - тут речь идет уже о нескольких секундах.Тут уже вопрос написания оптимального кода. - движуха по двум регистрам каждой его строки - это одна милисекунда на весь документ (не "для каждой его строки") - надо FIFO-цепочки выстроить по приходам, с которых "сдёргивается" каждая строка этого расхода. - это один запрос на весь документ (не "для каждой его строки") - Еще надо обновить баланс и обороты контрагента, записать инфу в аудит, да много чего еще надо. - ещё несколько коротких SQL-стейтментов. В общем, нужно просто всеми силами уменьшать время транзакции. Ещё могу посоветовать откладывать самые критичные (блокирующие других) изменения на конец общей транзакции. Ещё хороший способ уменьшить время блокировки - все вычисления, не требующие блокировки данных, выполнять перед началом общей транзакции. Ну и в итоге, как я и говорил, блокировка таблицы остатков слишком мала по сравнению с остальными действиями. Достаточно её перенести в конец транзакции, и эта одна милисекунда по сравнению с тысячами милисекунд транзакции ничего не будет значить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 15:21 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovalexeyvgСобственно, таблицы остатков и придумали, чтобы уменьшить нагрузку и блокировки, а не наоборот :-) Да, для СУБД в которых select-ы создают блокировки. Таковых, к счастью, теперь практически не осталось. Нет, не для этого. Во первых, блокировки делаются не случайно или по неопытности разработчиками движков СУБД, а совершенно намеренно для выполнения требований бизнес-логики. Во вторых, таблицы остатков делаются во всех реально эксплуатируемых системах, как с использованием ЭВМ и СУБД, так и без такового. Просто абсурдно перерасчитывать для каждого чтения горы исторических данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 15:28 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovalexeyvgСобственно, таблицы остатков и придумали, чтобы уменьшить нагрузку и блокировки, а не наоборот :-) Да, для СУБД в которых select-ы создают блокировки. Таковых, к счастью, теперь практически не осталось. Не говорите глупостей. Во всех более-менее адекватных СУБД используется наложение S-блокировки, если явно не указано обратного. Либо это может быть версионность, но это отдельная песня с отдельными заморочками, да и блокировка схемы накладывается по любому. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 15:34 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
alexeyvgПросто абсурдно перерасчитывать для каждого чтения горы исторических данных. Горы - да. Но тут речь идёт о (грубо говоря) остатке на полночь плюс движение за сегодня. iljyВо всех более-менее адекватных СУБД используется наложение S-блокировки, если явно не указано обратного. Перечислите три таких СУБД, накладывающих S-блокировки на таблицу при чтении. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 15:42 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovНо тут речь идёт о (грубо говоря) остатке на полночь плюс движение за сегодня.Я согласен, что в данном случае не критично. Только вы-то говорили совсем другое: Таблицы остатков придумали для СУБД в которых select-ы создают блокировки. А это не так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 15:53 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
alexeyvgТолько вы-то говорили совсем другое: Таблицы остатков придумали для СУБД в которых select-ы создают блокировки. Да, в ответ на фразу "таблицы остатков и придумали, чтобы уменьшить нагрузку и блокировки ". Таблица остатков, как и прочие хранимые агрегаты делается чтобы снизить нагрузку от селектов, считающих суммы по движениям. Селекты блокировок не создают (что бы там ни говорил iliy). Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 16:18 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakoviljyВо всех более-менее адекватных СУБД используется наложение S-блокировки, если явно не указано обратного. Перечислите три таких СУБД, накладывающих S-блокировки на таблицу при чтении. Собственно говоря это все СУБД, не являющиеся чистыми версионниками. Навскидку - SyBase, MSSQL, DB2. Только не надо бить себя пяткой в грудь и кричать, что так делают только придурки/му**ки/динозавры, у чистых версионников свои проблемы, связанные в первую очередь с конфликтом версий при параллельном изменении. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 17:16 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakov, только блокировки накладываются не на всю таблицу естественно (хотя DB2 вроде до сих пор так делает), а на строки(с возможной эскалацией на страницу и таблицу) либо диапазон ключа. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 17:18 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
iljyтолько блокировки накладываются не на всю таблицу естественно (хотя DB2 вроде до сих пор так делает), а на строки(с возможной эскалацией на страницу и таблицу) либо диапазон ключа. А смысл в таких блокировках, если они не препятствуют добавлению в таблицу новых записей?.. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 17:56 |
|
||
|
Накоп. регистр колич. итогов: безблокировочная работа vs check qty>=0
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakoviljyтолько блокировки накладываются не на всю таблицу естественно (хотя DB2 вроде до сих пор так делает), а на строки(с возможной эскалацией на страницу и таблицу) либо диапазон ключа. А смысл в таких блокировках, если они не препятствуют добавлению в таблицу новых записей?.. Эмм... Вы знаете, что такое блокировка диапазона ключа (более общее название - предикатная блокировка, но она вроде в полном виде нигде не реализована)? Она накладывается на уровне SERIALIZABLE, решающем проблему фантомных чтений. А построчные блокировки используются на более низких уровнях изоляции - READ COMMITTED и REPEATABLE READ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2011, 19:03 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=37428864&tid=1542037]: |
0ms |
get settings: |
10ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
180ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
76ms |
get tp. blocked users: |
2ms |
| others: | 234ms |
| total: | 544ms |

| 0 / 0 |
