metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2009-04-28 12:15 pm

Опять же на тему "готовых" решений

В последних постах [livejournal.com profile] yakov_sirotkin про очередь асинхронной обработки задач упоминается, почему они отказались от "готового" решения в виде Oracle AQ: это дело есть только в определенных Edition оракла и при тестировании у них возникли какие-то баги в очередях.

А у меня в двух проектах есть такие задачи, с обработкой очередей. И вот я сразу себе представляю - приезжаем ставить софт, клиент сказал, что у него "есть Оракл", а по приезде оказывается что это Express Edition, а DBA, которые в случае глюков будут разбираться в них, вообще нет. "Сушите весла."

То же самое касается практически всех "готовых" решений для сложных задач, входящих в состав СУБД, ОС или там еще чего-нибудь инфраструктурного. Как только принято решение использовать что-то более сложное, чем базовые функции - с этой системы ты уже никуда не уйдешь и нужно изучать ее "вглубь" и надеятся, что в следующих релизах этот функционал не выкинут, не изменят условия лицензирования, и что он будет работать как надо в других окружениях, и что будет достаточное количество людей, его использующих, чтобы было с кем посоветоваться.

[identity profile] sergiej.livejournal.com 2009-04-29 02:27 pm (UTC)(link)
Прямые запросы это некошерно, если надо делать на базе - ХП которая вызывается с высокого уровня.
"чёткие границы" очень просто устанавливаются, логика подсказывает что функция будет оптимальнее производится на уровне базы - она там и реализуется, ХП выставляет формализованный интерфейс (набор параметров, как вы говорите) вот она и граница. Программер логики не лезет в процедуру которая не на его уровне, программер базы не грузится тем что там наверху происходит - оптимизирует процедуру если надо. Вот и всё.

[identity profile] alexclear.livejournal.com 2009-04-29 02:30 pm (UTC)(link)
Нет, там никто никого не "залочил". Запустился процесс изменения состояния документа (пользователи инициировал или сервис, не важно), в процессе изменения требуется поддержать логическию целостность: пока процесс не завершился другие не могут делать что-то пересекающееся.

Это и есть "залочил".
Не скейлится.

В данном примере - нужно блокировать другие процессы, если они захотят расходовать тот же товар, что имеется в номенклатуре документа.

А зачем?

Еще грубее: два манагера не могут продать по 5 банок краски, если на складе их всего 5 даже если их процессы запустятся одновременно.

И не продадут.
Кто первый успеет изменить состояние, тот и папа, а второй не успеет.
ЛОЧИТЬ НИЧЕГО НЕ НАДО.
Надо просто использовать Hibernate и дуракцих проблем с дурацкими блокировками не будет.
Ну, или не Hibernate, а, я не знаю, здравый смысл.

[identity profile] alexclear.livejournal.com 2009-04-29 02:35 pm (UTC)(link)
Размер матрицы ACL - это круто, но откуда возьмутся большие накладные расходы, я опять не понял.
Права - это, практически, свойства объекта.
Аспект - это, практически, обработчик события.
Проверка прав будет происходить при наступлении события "обратились к".
Если же система прав накладывает существенные ограничения на размер выборки, то я бы такую систему прав выкинул, либо выборку делал бы как-то иначе.
Да, в случае необходимости существенно резать выборку именно правами на клиенте - расходы будут, согласен.
Но это тогда не система прав, а нечто прямо из ада.

[identity profile] sergiej.livejournal.com 2009-04-29 02:50 pm (UTC)(link)
1) ну и что? Их от этого что уже программировать и поддерживать не надо?
2) языки программирования высокого уровня не оперируют множествами?

[identity profile] metaclass.livejournal.com 2009-04-29 02:58 pm (UTC)(link)
В любом случае операция "проверить остаток и выполнить его списание" должна быть атомарной, т.е. блокировка этой сущности по которой остаток на время операции будет. Почему это нельзя сделать тремя запросами (а не 1000) - блокировка, проверка остатка, списание - не очень ясно. И почему эти запросы обязательно выполнять из SP в СУБД, а не из сервера приложений - тоже не очень понятно.

[identity profile] metaclass.livejournal.com 2009-04-29 03:01 pm (UTC)(link)
По первому - поддержка и программирование SP как бы и сложнее, чем на обычном языке.
А по второму - вроде только LINQ и оперирует, а все остальное при работе с множествами таки на порядок многословнее чем SQL

[identity profile] alexclear.livejournal.com 2009-04-29 03:05 pm (UTC)(link)
Ну да, будет compare-and-swap в случае optimistic locking.
Где-то должна быть атомарность, конечно.

[identity profile] sergiej.livejournal.com 2009-04-29 03:07 pm (UTC)(link)
Многословие не порок, порок когда слишком медленно. Базы данных должны хорошо хранить данные и ими быстро оперировать, пользоваться данными в большинстве случаев должен второй уровень. То что производительность при просчёте некоторых вещей лучше на базе - это надо делать на базе. Я вообще не вижу конфликта, меня злит только тупое одностороннее видение: я всё делаю на базе/я всё делаю на ООП/ я всё делаю на визуальных формах.

[identity profile] metaclass.livejournal.com 2009-04-29 03:11 pm (UTC)(link)
>Я вообще не вижу конфликта, меня злит только тупое одностороннее видение
Ну, я вот тоже не вижу противоречия между обоими подходами. Очевидно, что аггрегацию, сортировки и вообще все что хорошо ложится на SQL надо делать в базе, а всякую императивную интеллектуальщину - лучше на обычном языке.

[identity profile] sergiej.livejournal.com 2009-04-29 03:23 pm (UTC)(link)
Вот именно. Я видел работающую систему в которой ВСЁ было написано на PL/SQL абсолютно всё, страницы для пользователя в том числе и обработка всего HTTP. Оно работало... скажем так, запросы выполнялись очень быстро, но поддерживать её можно было исключительно: работает? - не трогайте. Интеграция с любой новой системой выливалась в месяцы разработки дорожайшими в мире специалистами, потом месяцами стабилизации. Когда вместо этого посадили пяток студентов, которые за неделю неоптимально и некрасиво присобачивали на жабе "любой каприз бизнеса", то "бизнес" вздохнул свободно, не надо больше ходить на поклон к волосатым хиппи знающим все дебри старой системы, которые кроме прочего умели небольшой ошибкой похерить половину базы.

[identity profile] alexclear.livejournal.com 2009-04-29 03:37 pm (UTC)(link)
Да я готов поверить, но не на слово.
Укажите, пожалуйста, сценарий, при котором предложенная стратегия не работает.

[identity profile] metaclass.livejournal.com 2009-04-29 04:17 pm (UTC)(link)
Даже если первой операцией с остатками идет их блокировка?

[identity profile] alexclear.livejournal.com 2009-04-29 05:48 pm (UTC)(link)
Я вообще не понимаю, зачем блокировать остатки, тоже мне, атомная станция.
Ну, обломается запись нового значения, так как кто-то раньше успел, ну, поймает клиент исключение.
"Ну не шмогла, не шмогла".
Вполне ведь штатная ситуация.

[identity profile] sergiej.livejournal.com 2009-04-29 06:18 pm (UTC)(link)
Берутся другие студенты и они опять фигачат простой неоптимальный код. Я однажды на спор блондинку которая всю жизнь работала барменшей взял и через две недели она решала несложные задачи по поддержке системы не хуже сидящего рядом консультанта из Аксенчера. Это не квантовая физика это простое ремесло.

[identity profile] alexclear.livejournal.com 2009-04-29 10:28 pm (UTC)(link)
Я дичайшим образом извиняюсь, а где я говорил про read committed?
Уровень изоляции транзакций на СУБД меня не волнует вообще, какой-то есть, да и ладно (собственно, "какой-то" это и есть read committed, не ниже).
Вы знакомы с механизмом работы optimistic locking?
Процесс номер один выхватит эксепшн "optimistic locking failed", или как его там при попыте списать 4 бочки краски, после чего transaction monitor в самом Hibernate откатит транзакцию.
И это, замечу еще раз, безо всяких там блокировок на уровне БД.
Что интересно, это будет работать на MySQL/MyISAM, в котором вообще нельзя транзакцию открыть на уровне СУБД.

[identity profile] alexclear.livejournal.com 2009-04-29 11:07 pm (UTC)(link)
Вы сначала попробуйте, будет ли это работать.

Вы всерьез думаете, что я сразу после окончания школы пришел сюда какие-то одному мне известные истины излагать?

Либо хибернатор блокирует объекты на своем уровне, не касаясь БД.

Опять мимо, да.
Скажите, пожалуйста, Вы когда-нибудь так называемую "версионную" БД видели?
Hibernate тупо добавляет ко всем таблицам еще одну int колонку.
Далее объяснять?

Тогда привет целостности от других приложений, например, если рядом шлюз B2B подкачивает документы из филиала.

Как я понимаю, J2EE приложение Вы тоже никогда не видели?
"Целостность от других приложений" - это что, откуда?
Кто же Вас в базу пустит-то в обход application server?
А на уровне application server с целостностью все хорошо, так как DAO layer общий. Я сейчас запамятовал уже, как называется этот стандарт, JPA, наверное, Java Persistence Architecture. Там не только Hibernate стандартизован.

Либо он переводит свои внутренние блокировки на уровень БД, запуская транзакцию с соответсвующим уровнем изоляции.

Мне крайне любопытно как Вы объяснили бы работу этого механизма на MySQL с хранилищем MyISAM.

"The other non-transactional storage engines in MySQL Server (such as MyISAM) follow a different paradigm for data integrity called “atomic operations.” In transactional terms, MyISAM tables effectively always operate in autocommit = 1 mode."

Как-то так.

Независимо от всего сказанного, в обоих случаях транзакция толстая, необходимо минимизировать ее время.

Я, на всякий случай, повторю еще раз, видимо, не последний.
Никакой блокировки нет. Попробуйте это понять.
Время транзакции минимизировать нет никакой нужды.
Кстати, а что такое "толстая транзакция"?
Ни разу не встречал такой термин.

[identity profile] alexclear.livejournal.com 2009-04-29 11:20 pm (UTC)(link)
Это самое - не будет никакой блокировки, что я говорю-то.
ЗАЧЕМ?
Там делается, как я представляю, тупо UPDATE .... SET ...., version=version+1 WHERE id=myid AND version=myversion
И если изменено будет ноль строк - приплыли, кто-то бампнул версию раньше, надо кидать эксепшн и откатывать транзакцию.
Кстати, что бывает на мускуле, когда в базу пишется несколько объектов в одном методе и обламывается не первая запись, я не помню, там же придется, по сути, откатить транзакцию, которой как бы нет.
Но мы это тоже как-то моделировали.

[identity profile] alexclear.livejournal.com 2009-04-29 11:26 pm (UTC)(link)
Во-первых, рекомендую почитать про версионные СУБД, чтобы не путать термины.

Я думаю, поскольку Вы продолжаете бой с тенью, термины путает та копия меня, которая у Вас в голове.

Во-вторых, поспрашивайте старших коллег, которым лет за 40, помнят ли они блокировки записей в Clipper/FoxPro/dBase и прочем файлсерверном хозяйстве.
Попросите их рассказать, как они еб.. мучились с этими висящими блокировками, если одно из приложений падало.


Я писал под R:Base и, представьте себе, тоже мучился с блокировками.
В критических случаях приходилось откатываться на бэкапный файл базы, правда, это на более поздних поделках, DOS-версия R:Base все же постабильнее была, чем позднейшие доработки.
И
что?

В-третьих, вы до сих пор не допетрили, что ежели кто-то кого-то ждет, неважно, в транзакции ли или вообще без нее (здравствуй, безпросветное бестранзакционное базоданностроение начала 1990-х), то значит блокировка имеет место быть.

Вы не могли бы мне еще раз показать, кто кого ждет?
Я, реально, столько раз объяснил, что сам уже понял.
Скажите, а Вы на каких языках вообще пишете, кроме SQL?
Можно я еще раз повторю, я уже привык: НИКТО НИКОГО НЕ ЖДЕТ, ВСЕ РАБОТАЮТ В ШТАТНОМ РЕЖИМЕ, НО ТОТ, КТО НЕ УСПЕЛ, ПОЛУЧАЕТ В ЛОБ ОТ ДВИЖКА.
Что я непонятно сказал, а?

В6четвертых, почитайте матчасть по уровням изоляции и попытайтесь понять, чем логическая изоляция отличается от физических блокировок.

Вы сейчас к чему это сказали, а?

[identity profile] sergiej.livejournal.com 2009-04-30 04:20 am (UTC)(link)
Вот именно.

[identity profile] metaclass.livejournal.com 2009-04-30 05:18 am (UTC)(link)
Ээээ. Для начала можно заблокировать остаток, а потом проверять. Т.е. второй процесс до проверки просто не дойдет, а когда дойдет - уже 5 бочек не будет.
А [livejournal.com profile] alexclear, судя по всему, вообще предлагает проверять постфактум(т.е. текущий остаток хранится явно и с проверкой Quantity>=0) - списывают оба, один получает отрицательный остаток и валится с ошибкой, которую мы обрабатываем на клиенте и выводим сообщение.

[identity profile] metaclass.livejournal.com 2009-04-30 05:25 am (UTC)(link)
Если мы сделаем в начале холостой апдейт нужной записи с остатком - то другая read committed транзакция либо свалится на этой же операции, либо будет ожидать завершения предыдущей. Вполне себе блокировка.

[identity profile] metaclass.livejournal.com 2009-04-30 05:29 am (UTC)(link)
Ой блин, теперь наконец то до меня дошло, что за механизм предлагается.
Использовать колонку версии или таймштампа чтобы при сохранении отследить, что запись меняли до нас и согласовать изменения или свалиться с ошибкой?

[identity profile] metaclass.livejournal.com 2009-04-30 05:32 am (UTC)(link)
Да, теперь понятно.

mysql в этом контексте пугает - если без транзакций откатывать изменения, то хибернету придется где-то у себя лог транзакции имитировать и откатывать его. Да еще как-то отличать базы - у которых можно откатить родную транзакцию, и у которых нужно ее откатывать вручную.

[identity profile] metaclass.livejournal.com 2009-04-30 05:39 am (UTC)(link)
Тут, как до меня наконец-то дошло, предлагается вот это:
http://en.wikipedia.org/wiki/Optimistic_concurrency_control

Т.е. даже блокировок не надо и висеть они не будут.

Хотя, кстати, висящие _явные_ блокировки (в виде флага "Занято") не настолько страшное дело - ну будет ходить специальный фоновый процесс, следить чтобы блокировки от отвалившихся юзеров снимались.
Я такое делаю в одном проекте, там обработка документа длительный процесс и выдаются они на обработку по 5 штук пользователю. Если пользователь отвалится - то или подключится через минуту и получит те же документы или же больше не подключится и флаг с документа будет снят через 5 минут и он будет выдан на обработку другому пользователю.

[identity profile] alexshubert.livejournal.com 2009-04-30 05:47 am (UTC)(link)
Я бы не взял на работу автора.

Page 2 of 3