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] alexclear.livejournal.com 2009-04-29 01:19 pm (UTC)(link)
В этом типовом примере проблемы начинаются в самой постановке задачи.
Другие пользователи не должны начинать курить, пусть себе работают.
А если этот пользователь залочил документ, и его молнией убило?
Почему нельзя использовать optimistic locking, я не понимаю?
(deleted comment)

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

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

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

А зачем?

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

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

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

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

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

[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, в котором вообще нельзя транзакцию открыть на уровне СУБД.
(deleted comment)

[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."

Как-то так.

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

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

[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четвертых, почитайте матчасть по уровням изоляции и попытайтесь понять, чем логическая изоляция отличается от физических блокировок.

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

(no subject)

[identity profile] metaclass.livejournal.com - 2009-05-01 07:26 (UTC) - Expand

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

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

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

(no subject)

[identity profile] alexshubert.livejournal.com - 2009-04-30 05:57 (UTC) - Expand

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

(no subject)

[identity profile] alexclear.livejournal.com - 2009-04-30 07:35 (UTC) - Expand
(deleted comment)

(no subject)

[identity profile] metaclass.livejournal.com - 2009-05-01 07:29 (UTC) - Expand
(deleted comment)

(no subject)

[identity profile] metaclass.livejournal.com - 2009-05-01 14:36 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2009-05-01 07:37 (UTC) - Expand
(deleted comment)

(no subject)

[identity profile] vp.livejournal.com - 2009-05-01 12:03 (UTC) - Expand

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

[identity profile] alexshubert.livejournal.com 2009-04-30 05:51 am (UTC)(link)
Read commited здесь недостаточен.
да ну. no rec version + timeout

[identity profile] alexshubert.livejournal.com 2009-04-30 05:50 am (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)
Я вообще не понимаю, зачем блокировать остатки, тоже мне, атомная станция.
Ну, обломается запись нового значения, так как кто-то раньше успел, ну, поймает клиент исключение.
"Ну не шмогла, не шмогла".
Вполне ведь штатная ситуация.
(deleted comment)

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

[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] metaclass.livejournal.com 2009-04-30 05:32 am (UTC)(link)
Да, теперь понятно.

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

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