Логическая блокировка записи при многопользовательской работе приложения

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Аватара пользователя
ingasoftplus
Ветеран
Сообщения: 426
Зарегистрирован: 26 Декабрь 2006, 17:07
Откуда: Оттуда :)
Благодарил (а): 90 раз
Поблагодарили: 5 раз

Логическая блокировка записи при многопользовательской работе приложения

Сообщение ingasoftplus »

Да, я опять про многопользовательску работу приложения! Вот в конце концов налетели на это.

Прога на с55, MS SQL. Проблема банальна - броуз / форма (и не только, возможно обновление напрямую через сорс код например по кнопке). Как известно, 2 (и больше) разных юзера могут начать редактировать 1 запись. Первый из них - может сохранить изменения, другие получат отлуп что дескать запись именена на друг рабочей станции. Это не дело! И проблема даже не в том, то другие юзеры могут долго вносить изменения и потом все потерять что есть свинство.

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

Нужно приемлемое решение, когда первый юзер "берет" запись, то она должна каким-то образом быть помечена "в работе/ блокирована". Другие юзеры (или даже он сам в другой сессии!) при попытке взять запись должны будут знать, что данная запись уже захвачена!
В целом это было бы решение.

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

Разумеется, каждый юзер в нашей системе авторизован и есть все его данные.

Хотелось бы системного и надежного решения данного вопроса, что-то типа менеджера. Где бы было видно, кто работает с данной записью, что бы запись блокировалась для данного юзера (в момент его огбращения к записи и разумеется проверки, что запись не блокирована), возможность разблокирования записи в случае аварии и т.п.

Т.е нужна "блокировка" записи не на уровне движка базы данных а "блокировка" на уровне бизнес логики.

Есть ли такие наработки? Решения? Идеи?
Последний раз редактировалось ingasoftplus 27 Февраль 2015, 1:42, всего редактировалось 1 раз.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7378
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Логическая блокировка записи при многопользовательской работе приложения

Сообщение Игорь Столяров »

Пример сообщения, при попытке повторно редактировать документ.
Пример сообщения, при попытке повторно редактировать документ.
Есть реализованная идея. :)
Все тривиально и реализовать можно на любой структуре данных.
Мы сделали для TPS / Btrieve, поскольку при работе без поддержки БД на стороне сервера, когда юзеры одновременно
в одни и те же документы, создается масса проблем, кроме неприятного сообщения. Особенно в составных документах
(например накладные с содержанием, где один юзер может добавлять записи в содержание, а другой их удалять).
На SQL это все есть во внутренних механизмах ядра БД, но написанная вручную логика позволяет гибко управлять процессом.

Открытие всех карточек документов вызывается из процедуры-менеджера, которая ведет отдельный список кто,
в каком режиме, когда открыл на изменение запись в БД. При завершении редактирования - запись удаляется.
При попытке открытия - проверяется, не занята ли запись другим пользователем (см. рисунок).
Очевидная проблема: при вылете пользователя, запись остается заблокированной.
Решается проверкой при запуске программы наличие заблокированных более 1 часа записей и их разблокировка.
Также есть "ручной" сброс заблокированных записей для пользователя с правами администратора. Вот и все.

Главное: в самих редактируемых записях нет никаких флагов блокировки (мы это проходили, тупиковый путь).
Номер списка + номер записи в списке - это уникальный признак, по которому создается запись в списке блокировок.
Как дополнительная приятность - обрабатываются случаи, когда пользователь в одной копии программы пытается
редактировать один и тот же документ (например из основного списка документов и списка запроса на поиск).
Не надо искать заблокированные записи во всех списках - очистили один файл блокировок и разблокировали все
записи во всех списках. Все блокировки для всех списков видны в одной таблице.
Т.е. получилось, что-то вроде управляемого Hold() / Release(). :) (с ними тоже в свое время натерпелись).

Модификация списка блокировок (добавление, удаление) естественно выполняется под транзакцией.
В одной фирме предложили ящик пива, если им удастся с 2-х компьютеров открыть одновременно
один документ на редактирование. Пробовали одновременно с 5 компьютеров, если не ошибаюсь,
так ничего и не вышло. :)

В принципе, идея оказалась настолько удачной, что кроме документов, мы на нее повесили еще и блокировку
основных справочников. Исчезла масса проблем, кол-во обращений в тех. поддержку с разрушенными TPS
файлами сократилось на порядок, как минимум.
Последний раз редактировалось Игорь Столяров 27 Февраль 2015, 7:53, всего редактировалось 1 раз.
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
ingasoftplus
Ветеран
Сообщения: 426
Зарегистрирован: 26 Декабрь 2006, 17:07
Откуда: Оттуда :)
Благодарил (а): 90 раз
Поблагодарили: 5 раз

Многопользовательская работа приложения

Сообщение ingasoftplus »

Игорь, спасибо за ответ. Идея в общем виде понятна. (только рисунка не нашел :) )

а можно конкретней? ну хотя бы описание таблицы блокировки, кусочки кода... процедура-менеджер ?? :oops:

Геннадий
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7378
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Многопользовательская работа приложения

Сообщение Игорь Столяров »

Да, я написал админу в группу по обсуждению форума - не прикрепляет у меня картинки, говорил "лимит исчерпан" :(

Я попробую, что-то написать ... но в общем-то особого смысла в этом нет.
Во первых у меня не SQL. Во вторых я описал идею в примитиве.
В реальности списки поддерживают групповую обработку (можно выбрать несколько записей и удалить одной командой)
и поэтому код достаточно накрученный. В третьих - структура таблицы блокировки зависит от того какие данные есть в
системе и нужны. Как я уже написал: уникальный параметр - это номер таблицы + номер редактируемой записи в этой таблице.
Все. Более ничего не нужно. Но мы храним дату и время блокировки (для автоочистки зависших записей через час), параметры
оператора, который работал с записью - для выдачи сообщения. Надеюсь прикрепление файлов починят - на рисунке это видно.
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
ingasoftplus
Ветеран
Сообщения: 426
Зарегистрирован: 26 Декабрь 2006, 17:07
Откуда: Оттуда :)
Благодарил (а): 90 раз
Поблагодарили: 5 раз

Многопользовательская работа приложения

Сообщение ingasoftplus »

Игорь Столяров писал(а): Уникальный параметр - это номер таблицы + номер редактируемой записи в этой таблице
вот тут не понятно с терминологией.

что такое - это номер таблицы? как поле таблицы и содержимое этого поля??
номер редактируемой записи? это уник ID (autoincremental unique number)???

поэтому и просил структуру таблицы - так было бы понятно.

картинку ну и если еще что есть можно и на мыло кинуть, если можно info@ingasoftplus.com
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7378
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Многопользовательская работа приложения

Сообщение Игорь Столяров »

Номер таблицы - это какой-либо уникальный ID. Мы просто пронумеровали все таблицы от 1 до N.
Можно в качестве ID Использовать имя таблицы и т.д.

Да, номер записи - это уникальный код записи в списке, ее ID в списке.

Поэтому эти два параметра однозначно определяют редактируемую запись.
Картинку отправил.
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
ingasoftplus
Ветеран
Сообщения: 426
Зарегистрирован: 26 Декабрь 2006, 17:07
Откуда: Оттуда :)
Благодарил (а): 90 раз
Поблагодарили: 5 раз

Многопользовательская работа приложения

Сообщение ingasoftplus »

ага... теперь более понятно :)

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

Геннадий
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Многопользовательская работа приложения

Сообщение Yufil »

Я делал каталог, доступный всем пользователям (например, \\SERVER\Lock)
При открытии документа в БД программа создаёт в этом каталоге и монопольно открывает файл (например, idДокумента.idОператора.lock)
Но перед этим программа пытается удалить из каталога все файлы idДокумента.*
Если хотя бы один такой файл остался - документ занят, по имени файла можно определить оператора и выдать сообщение, кто именно заблокировал, если нет-создаём свой файл. После завершения редактирования документа файл закрывается и удаляется.

Здесь в плюс - при слёте программы файл будет разблокирован и удалён.
Ну и полезно при пуске или закрытии программы попробовать удалить все файлы в этом каталоге.
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

Многопользовательская работа приложения

Сообщение Shur »

Первый из них - может сохранить изменения, другие получат отлуп что дескать запись именена на друг рабочей станции. Это не дело! И проблема даже не в том, то другие юзеры могут долго вносить изменения и потом все потерять что есть свинство.
Мне всегда казалось, что concurrency check есть одна из основных фишек Клариона, которую до сих пор мало кто сумел реализовать да ещё и на уровне языка и поддерживающих это шаблонов. Поэтому прошу точнее выражаться, мол, мы хотим отойти от стандартной парадигмы, как это грамотно сделать.

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

Код: Выделить всё

TAB:record.MySave = TAB:record
TAB:Memo.MySave = TAB:Memo
а потом, после появления сообщения и обновления полей зафиксированными значениями, предложить восстановить запись в вашей редакции

Код: Выделить всё

if message('Restore record?',...) = BUTTON:Yes   
   TAB:record = TAB:record.MySave
   TAB:Memo = TAB:Memo.MySave
end   
и обновить экранные поля.

Подойдёт такой вариант без отказа от concurrency check?
Последний раз редактировалось Shur 27 Февраль 2015, 0:49, всего редактировалось 1 раз.
Аватара пользователя
ingasoftplus
Ветеран
Сообщения: 426
Зарегистрирован: 26 Декабрь 2006, 17:07
Откуда: Оттуда :)
Благодарил (а): 90 раз
Поблагодарили: 5 раз

Многопользовательская работа приложения

Сообщение ingasoftplus »

Шур, спасибо за ответ.

Но проблема тут даже не в том, чтоб пытаться любой ценой сохранить свои изменения в таблице, после того, когда кто-то другой уже внес свои изменения. Мне нужно НЕ ДАТЬ возможность вообще входить в режим редактирования, если запись уже логически "блокирована" другим юзером.

Юрий, спасибо за идею.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7378
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Логическая блокировка записи при многопользовательской работе приложения

Сообщение Игорь Столяров »

Shur писал(а): Мне всегда казалось, что concurrency check есть одна из основных фишек Клариона
Очень красивое решение с точки зрения теории структуры БД / программирования и абсолютно бестолковый прибамбас в реальности.

1. Как я уже написал - записи бывают составные (накладная с содержанием). Что дает предложение "восстановить или отменить"
данные накладной при попытке ее сохранить, когда пользователь пол часа редактировал содержание этой накладной ?
В этом случае надо делать и восстанавливать еще и всю структуру содержания накладной.
Хотя здесь перед пользователем ставится еще более сложная задача выбора: либо отменить и потерять всю сделанную
работу, либо дождаться завершения редактирования записи другим пользователем, и вслепую (!!!) затереть результат его работы своим. :(

2. А вообще работа "concurrency check", образно говоря, напоминает ситуацию, когда ты уже приготовился, открываешь крышку унитаза, а там лежит табличка "НЕ РАБОТАЕТ". Почему бы эту табличку не разместить на входе в туалет, если в нем все равно нельзя выполнить заявленное действие ? ;)
За теми кто отстал - не возвращаться. (С) Кодекс
kreator
✯ Ветеран ✯
Сообщения: 4984
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 20 раз

Логическая блокировка записи при многопользовательской работе приложения

Сообщение kreator »

А у меня вопрос вот такой. А как так получается, что пользователи могут редактировать одну и ту же запись? Если это случайность, то стандартного кларионовского механизма, думаю, достаточно. А если это принцип работы, то, да, надо что-то думать. Но у меня на вскидку не получается представить бизнес логику такой работы. Например, по-моему опыту работы в Бухгалтерии / Торговле / Складе изменения документов (Накладных) производятся очень редко, и даже не понятно, что там менять? А содержимое документов (позиции накладной, впрочем как и поля этой накладной) редактировать можно регулировать доступом, имеет право редактировать только создатель, если его нет, то сначала измени создателя, а потом редактируй.
We are hard at work… for you. :)
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

Логическая блокировка записи при многопользовательской работе приложения

Сообщение Shur »

Совершенно согласен с Kreator'ом. Если вы редактируете уже созданную накладную (да ещё и в 4 руки) по полчаса, то надо менять бизнес-процесс, поскольку в имеющемся что-то совершенно не верно.
Далее. Что в накладной можно вообще менять? Если строки, то они фиксируются каждая сама по себе.
Далее. Если приходит сообщение, что запись изменена (а под записью в данном случае мы здесь понимаем накладную), то правильным поведением будет выйти из редактирования как можно скорее от греха и связаться с исправившим эту накладную сотрудником. Но это, опять-таки, к правильности используемых бизнес-процессов.

P.S. Во всяком случае, если бы у вас было финансовое приложение, то вы бы так пренебрежительно о конкурентной записи не выражались, а использовали бы его как защиту о возможных финансовых потерь, возникших в результате каких-либо коллизий.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7378
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Логическая блокировка записи при многопользовательской работе приложения

Сообщение Игорь Столяров »

kreator писал(а): А содержимое документов (позиции накладной, впрочем как и поля этой накладной) редактировать можно регулировать доступом, имеет право редактировать только создатель, если его нет, то сначала измени создателя, а потом редактируй.
Было бы здорово, но Вы смотрите на мир в розовых очках. Давайте упростим, что бы не тратить время на обсуждение бизнес-процессов и их длительность на форуме программистов. Предположим у нас есть справочник контрагентов и обычная торговая фирма с десятком компьютеров. Менеджер может редактировать в карточке контрагента контактные реквизиты, а бухгалтер в это же время может попытаться набрать адрес для счет-фактуры, кладовщик исправлять место доставки товаров и т.д.

Да, в идеале, было бы здорово, что бы все изменения в карточку контрагента вносил один пользователь, с правами на такое действие.
Но в реальности - они все имеют права на такие действия. И задача программы (программиста) - грамотно организовать этот процесс при многопользовательской работе, а не учить клиента жизни - как ему нужно организовать работу с данными контрагента. Особенно если программа серийная и с ней работают сотни фирм, которые ты вообще никогда не видел.
За теми кто отстал - не возвращаться. (С) Кодекс
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

Логическая блокировка записи при многопользовательской работе приложения

Сообщение Shur »

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

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

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

Про розовые очки я бы не стал говорить. Всё-таки у многих из нас есть опыт работы в торговых фирмах по многу лет. И надеюсь, что сравнение concurrency check с унитазом будет дезавуировано -- он вам точно ничем не помешал, скорее вы не сумели его для себя приспособить.
Ответить