пессимистическое блокирование

gs-design

Новичок
Добрый день!

Подскажите, возможно ли применение запроса в ПХП типо: "SELECT .... FOR UPDATE" при условии, что секция "UPDATE ..." будет вызываться пользователем позже?

Проблема в том, что когда скрипт заканчивает работу - соединение с БД разрывается и незавершённые транзакции откатываются...

Если есть решение, приведите, пожалуйста пример или ссылку на материал.

Спасибо
 

Gas

может по одной?
Подскажите, возможно ли применение запроса в ПХП типо: "SELECT .... FOR UPDATE" при условии, что секция "UPDATE ..." будет вызываться пользователем позже?
вообще-то так всегда и происходит, сначала for update, потом update. Или ты хочешь чтоб при первом выполнении скрипта поставилась блокировка, скрипт отработал, запустился ещё раз и только потом update? Ты не должен этого хотеть, что-то у тебя не так придумано. Если используется не pconnect, то естественно при разрыве соединения всё что не закомичено ролбечится. Что там при persistent connection происходит не знаю, но ради такого не стоит на него переходить.
 

gs-design

Новичок
Или ты хочешь чтоб при первом выполнении скрипта поставилась блокировка, скрипт отработал, запустился ещё раз и только потом update? Ты не должен этого хотеть, что-то у тебя не так придумано. .
Ситуация простая - пишу пользовательский интерфейс для обработки денежных данных (их распределения). Схема такая:
1 - выбираю сумму
2 - отдаю веб-мордочку клиенту
3 - клиент вводит данные и отсылает на сервер
4 - данные заносятся в базу.

Логично в 1 открыть транзакцию и создать SELECT ... FOR UPDATE NO WAIT ,
а в 4 - сделать закрытие транзакции... Но, я так понимаю, что в п.2 происходит закрытие скрипта, а в 4 - открытие нового. Вот и спрашивается, как организовать "удержание" транзакции?

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

Gas

может по одной?
Вообще-то, в основном пессимистическое блокирование и юзается с пользовательским интерфейсом, где большие задержки в обновлении данных, для сохранения целостности.... Или я что-то не так понимаю?
имхо, не обязательно наличие больших задержек, достаточно просто большой конкурентности (или теоритической её возможности, особенно когда речь идёт о деньгах).
но я сейчас понял что ты не написал с какой базой работаешь, а я высказываюсь на основании своих знаний по mysql и немного postgresql.
Если у тебя oracle/mssql, то там могут быть какие-то свои стандартные решения.

Ну а если в целом, пока не совсем понимаю зачем делать for update где-то вначале, а не на 4-м шаге если там есть необходимость. Чтоб когда человек начал но пока человек не прошёл 4-ый шаг, то ещё раз не зашёл на 1-ый ?
 

gs-design

Новичок
Ну а если в целом, пока не совсем понимаю зачем делать for update где-то вначале, а не на 4-м шаге если там есть необходимость. Чтоб когда человек начал но пока человек не прошёл 4-ый шаг, то ещё раз не зашёл на 1-ый ?
Моя база на PostgreSQL. Такой совет не есть правильный, особенно для денежных операций (По этому поводу можно почитать Тома Кайта). И проще/правильнее пользователю выдать сообщение : Запись кем-то редактируется, чем после 5 минут занесения информации: Ой, а данные изменены другим пользователем... Попробуете ещё раз?;)

Кроме того я не рассматриваю, что лучше - оптимистическое (которое описываете ВЫ) или пессимистическое... Мне интересен именно вариант реализации на ПХП пессимистического блокирования средствами БД. Если знаете варианты/примеры - буду признателен, за расширение и моего кругозора.
 

Gas

может по одной?
Такой совет не есть правильный, особенно для денежных операций. И проще/правильнее пользователю выдать сообщение
имхо, для денежных операций самое главное чтоб целостность данных не нарушилась, а оптимистическая или пессимистическая блокировка использовалась думаю большой роли не играет.
"проще" - не думаю, с учётом специфики http.
"правильнее" - согласен.

Запись кем-то редактируется, чем после 5 минут занесения информации: Ой, а данные изменены другим пользователем... Попробуете ещё раз?
не встречал реализации пободного за счёт блокировок базы, обычно c помощью всяких ajax'ов + сравнения времени делают (но это конечно не суммы денег редактируют).

Мне интересен именно вариант реализации на ПХП пессимистического блокирования средствами БД.
мне тоже интересно, решения я не знаю и даже не уверен что оно существует, блокировки сбрасываются в момент commit/rollback, при закрытии соединения это 100% происходит. Для случая с pconnect или pgpool, если рассуждать (сам не пробовал), то транзакции тоже наверное должны закрываться. Иначе я не просто не представляю, запускается случайный процесс, получает соединение с базой, а там незаконченная другим процессом транзакция. Как-то странно выглядит.
Но ещё раз говорю, я до конца не в теме и это только рассуждения, самому интересно :)
Спроси на sql.ru или может сюда админ postgres форума заглянет и отпишет чего.
 

iceman

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

Том Кайта читал, так чо - делай, только уже на ПХП+PG а не только в PG
 

MiksIr

miksir@home:~$
Да все верно, у транзакций задача - целостность данных внутри базы и ожидание действия пользователя сюдя не подходит.
Свои блокировки или проверка изменнности данных при сохранении.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
в постгресе можно просто начать транзакцию, и для денежных полей надо выставить check balance>0 в таблице
при правильном подходе блокировок не будет, изменения по коммиту могут суммироваться, а проверка не даст закоммитить отрицательный балланс
 

gs-design

Новичок
в постгресе можно просто начать транзакцию, и для денежных полей надо выставить check balance>0 в таблице
при правильном подходе блокировок не будет
При всём уважении, видимо Вы не совсем понимаете смысл блокировок. Простая задача - начисление ЗП. 2 бухгалтера одновременно Вам начислят деньги и проверка check balance>0 очень даже нарушена не будет, а результат совсем другой...

Лично я, если кому интересно, данную проблему сейчас обхожу таким способом:

В нужных таблицах есть 2 поле типа varchar(n) туда записываю время "блокировки" и кто блокирнул. Остальные уходят, если поля стоят - уходят курить... Время надо для того, чтоб в случае обвала, через 1 час (у меня так) эта запись была доступна другим. Прочитал - заполнил поля.... Перед записью - проверил установлено или нет (вдруг время прошло или ишо что). Записал обнулил поля поля...

+ Таблица больше не весит
+ Аналог пессимистической блокировки

- Дольше операция
- Реализовывать надо ручками и ВЕЗДЕ это поддерживать
- Пока не придумал варианта со множественной блокировкой... но думаю :)

Да, использование RETURNING <имя поля> - существенно сокращает и ускоряет код...
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
если 2 бухгалтера начисляют двойную з/п одному сотруднику - надо менять главбуха
от ошибки бухгалтера ни одна программа не поможет

не, ты делай, делай, у вас там явно техдира менять надо, раз сотрудники такие алгоритмы придумывают
 

MiksIr

miksir@home:~$
Можно, как я уже говорил, проверять на измененность при сохранении. В этом случае никто не ждет, но кто первый сохранил, то и выиграл, а второй при сохранении видит, что в базе другие данные чем были получены ранее, а значит сохранять ничего нельзя. Это в общем более простая схема, так как не требует дополнительных полей - достаточно хранить хеш от данных... ну или если есть поле "дата изменения" - то просто его.
 

gs-design

Новичок
если 2 бухгалтера начисляют двойную з/п одному сотруднику - надо менять главбуха
от ошибки бухгалтера ни одна программа не поможет

не, ты делай, делай, у вас там явно техдира менять надо, раз сотрудники такие алгоритмы придумывают
Из текста видно, что с распределёнными сетевыми задачами явно Вы не очень сталкивались... Например в 1С есть ВЕБ морда, которая частично решает задачи прикладного приложения. Я пишу аналог ЕРП для ведения хозяйственных операций. Сейчас основной язык - PHP, но очень уже начинаю смотреть в сторону Java. А ситуация, когда не разрешить двум УДАЛЁННЫМ пользователям одновременно редактировать одну и ту же запись в БД - задача программиста и его кода. Да возможно у Вас и есть такая бухгалтерия (больше 1-го человека) которая в рупор предупреждает остальных, что каждый из бухгалтеров собирается делать... Но видите в чём дело, в программах эти задачи решаются на прикладном уровне, а ещё лучше средствами БД.
 

gs-design

Новичок
Можно, как я уже говорил, проверять на измененность при сохранении. В этом случае никто не ждет, но кто первый сохранил, то и выиграл, а второй при сохранении видит, что в базе другие данные чем были получены ранее, а значит сохранять ничего нельзя. Это в общем более простая схема, так как не требует дополнительных полей - достаточно хранить хеш от данных... ну или если есть поле "дата изменения" - то просто его.
Этот вариант называется оптимистическое блокирование, и не входит в название топика. Такой вариант подходит для задач, где мало пользователей/минимальны изменения и т.д. ПОЛЬЗОВАТЕЛЬ должен быть уверен, что то что он набирает - попадёт в БД.
 

MiksIr

miksir@home:~$
Это вопрос взаимодействия. Если вы нормально отреагируете пользователю на такую ситуацию - задача отлично решается. Но если вас больше устраивает в системе, где _очень много поользователей и изменений_, что все эти пользователи ждут десятки минут таймаута, пока менеджер, открывший изменение, пьет кофе - то ваше право. Только не забудьте, что попив кофе он захочет все же сохранить свои изменения.
И хватит тут уже терминами из википедии сыпать. Если были бы такие умные - не задавали таких глупых вопросов (а они уровня начинающего, уж извините).
 

gs-design

Новичок
Это вопрос взаимодействия. Если вы нормально отреагируете пользователю на такую ситуацию - задача отлично решается. Но если вас больше устраивает в системе, где _очень много поользователей и изменений_, что все эти пользователи ждут десятки минут таймаута, пока менеджер, открывший изменение, пьет кофе - то ваше право. Только не забудьте, что попив кофе он захочет все же сохранить свои изменения.
И хватит тут уже терминами из википедии сыпать. Если были бы такие умные - не задавали таких глупых вопросов (а они уровня начинающего, уж извините).
Я из википедии ничего не сыплю. Вопрос звучал просто - можно или нет. Если читать мои коменты, то логично предположить, что я реализую механиз с предположения, что нельзя.
Поинтересовался, из предположения, что мне смогут помочь, а вопрос из ПХП как-то плавно перекочевал в разряд как правильно писать на SQL и какие блокировки использовать.

А по поводу "Попить кофе" - есть такая вещь, как мониторинг работы пользователей + премия в конце месяца и т.д.

Если нет конкретных примеров реализации использующих смысл ТРАНЗАКЦИИ и ПЕССИМИСТИЧЕСКОЙ БЛОКИРОВКИ из СУБД в рамках ПХП или его расширений, вопрос можно считать ЗАКРЫТЫМ. Кому интересно - один из примеров реализации я уже написал выше.
 

Gas

может по одной?
Прочитал - заполнил поля.... Перед записью - проверил установлено или нет
только это тоже нужно сделать правильно, а не как 90% рядовых php-шников :)

(я for update имею ввиду)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
очень мало шансов, что это интересно кому-то, кроме тебя
в мире PHP подобные задачи решаются совсем иначе
 

gs-design

Новичок
очень мало шансов, что это интересно кому-то, кроме тебя
в мире PHP подобные задачи решаются совсем иначе
Вот тут то ближе к теме:)
Знаешь как решаются подобные задачи - приведи пример/дай ссылку. Буду искренне благодарен.
Одно маленькое НО - реализация - ERP на базе веб интерфейса: аналог 1С бухгалтерии с веб интерфейсом.
 
Сверху