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

Clarion, Clarion 7

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

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

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

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

Да, действительно "concurrency check" ничем не мешает, просто, на мой субъективный взгляд, это абсолютно не рабочий алгоритм.
И я не услышал как его и для чего можно приспособить.
Его использование - просто демонстрация возможностей по контролю состояния данных.

Давайте абстрагируемся вообще от каких-либо конкретных данных, это совсем другая история.
Не будем увеличивать классическое кол-во вопросов, в которых все являются большими специалистами. ;)
Попробуем обсудить общую алгоритмику и найти решение вопроса.

1. Есть некая запись в списке, в БД с многопользовательским доступом.

2. Пользователь №1 открывает запись на редактирование, возможно для того, что бы внести в нее изменения.
Это не моментальный процесс, он занимает некоторое время, предположим N сек.
Доступ к списку многопользовательский - мы не можем блокировать к нему доступ на время этой операции,
более того, мы не запрещаем просматривать данные этой записи другим пользователям.

3. Пользователь №2 открывает эту же запись на изменение и тоже вносит в нее изменения.
У него этот процесс занимает, предположим K сек.

4. И вот теперь получается, что успешность выполнения операции изменения записи, для обоих
пользователей становится зависимым и более того, для обоих успешность не гарантирована.
В зависимости от пересечения интервалов N и К - один из пользователей может получить
(или не получить) сообщение concurrency check о том, что редактируемая запись была изменена
и сохранение результата невозможно. Путем предлагаемой настройки ее функционала, можно
выполнить восстановление первоначальных данных, можно пойти дальше, предложить и
принудительно выполнить запись изменений.

5. Т.е. любое использование concurrency check приведет к коллизии: либо будут потеряны данные
набранные пользователем, либо будут затерты данные другого пользователя, без его ведома.
Тогда какой в ней смысл ? В информации о том, что запись была уже кем-то изменена ?
Если я бронирую билет в кинотеатр по телефону, то какая мне радость в информации на кассе,
что мой билет был продан, пока я ехал в кинотеатр ? ;)

6. Как можно приспособить concurrency check для эффективной работы ?
Расскажите пожалуйста, как можно его "себе приспособить" ? Я буду благодарен.
На мой взгляд решение только одно - тем или иным способом отслеживать редактирование записи
и запрещать выполнение повторного редактирования, до завершения предыдущего.
А в этом случае concurrency check - вообще не нужен, он просто тратит ресурсы, хотя и не мешает ...

Вот и все. :) Или я не прав ? ;)
Make Clarion Great Again ! 😎
Аватара пользователя
Admin
Администратор
Сообщения: 4010
Зарегистрирован: 05 Июль 2005, 15:59
Откуда: Хабаровск
Благодарил (а): 53 раза
Поблагодарили: 33 раза
Контактная информация:

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

Сообщение Admin »

Все много написали. Напишу и я.
Не сталкивался за 20 лет с проблемой этой.
Стандартной блокировки достаточно для работы всегда.
Рай совершает ошибки ничуть не реже чем ад. Просто у него хорошая пресса
kreator
✯ Ветеран ✯
Сообщения: 5161
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 11 раз
Поблагодарили: 26 раз

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

Сообщение kreator »

Я вот ещё 5 копеек добавлю.
Есть опыт работы в конкретной продажной конторе. Менеджеры работают так: пришли на работу, включили программу, зашли в какую-нибудь накладную (типа, работаем) и сидят, чай пьют. По хорошему, надо запись заблокировать, а остальные сотрудники будут звонить тому кто заблокировал и спрашивать "что ты делаешь в такой-то накладной". А тот менеджер чай пьёт на диванчике, ему лень по внутреннему номеру ответить, он дёрнется только к городскому звонку. И пока не дойдёшь до места чаепития, работа не сдвинется. Притом что конкретный менеджер даже не собирается что-то править, просто чай попьёт и выйдет из редактирования. Такая работа нужна?
Второй момент. Опять конкретный. Вероятность, что бухгалтер и кладовщик одновременно будут править карточку клиента близка к нулю, притом, что это работа менеджера по продажам. Изменения в реквизитах, как правило, делает менеджер, который ведёт этого клиента. Работа бухгалтера и кладовщика в другом.
Ну и если посмотреть как это делается в SQL. Я, так понимаю, никак. Кто последним послал запрос на изменение, того и тапки.
We are hard at work… for you. :)
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

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

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

kreator писал(а): Кто последним послал запрос на изменение, того и тапки
В нашем случае - наоборот. Кто первый послал запрос, того и тапки.
А тот кто последний послал запрос - тот получил информацию, о том, что запись изменена с другой рабочей станции. :)

А в SQL это делается по разному. Хотя бы тому, что там есть возможность блокировки конкретной записи (и даже конкретных полей).
Make Clarion Great Again ! 😎
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

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

Сообщение Shur »

Ну и если посмотреть как это делается в SQL. Я, так понимаю, никак. Кто последним послал запрос на изменение, того и тапки.
Тут надо как бы несколько подразделять: работу собственно СУБД и работу user-friendly интерфейса, который обеспечивает полноценную работу с ней. СУБД, будь то SQL или TopSpeed, не может поступить иначе.

А вот если принцип "Last Wins" закладывается в работу интерфейса, то это самое опасное, что может быть. Этот принцип сейчас чрезвычайно распространился, ведь программировать стало довольно просто, программируют все, кому не лень. А образования соответствующего нет.
Так вот, всерьёз обсуждать этот метод на страницах этого форума вообще мне не представляется нужным и возможным.

Теперь о следующих двух. Блокирование записей на изменение (pessimistic concurrency control), на мой взгляд, есть некая перестраховка, а вот concurrency check, или optimistic concurrency control, это высшая лига в программировании БД.

Теперь о том, где это применимо. Представьте, вы действительно пытаетесь купить себе билеты на поезд или в кино. Optimistic concurrency control действует до тех пор, пока вы не перейдёте к оплате билетов, когда вступает в силу блокировка этих мест до момента оплаты или по тайм-ауту. Фактически, если представить, что место в вагоне/зале это та самая запись, то и получается, первый пользователь успел первым сохранить запись и, тем самым, занять это место, а вы, попивающий чай, при обновлении окна будете оповещены, что это место уже куплено и вам предстоит заново выбрать место себе из оставшихся.
Последний раз редактировалось Shur 27 Февраль 2015, 15:53, всего редактировалось 1 раз.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

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

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

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

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

А вот если после выполнения некого объема работы (ввода всей информации о пассажире, его паспорте и т.д.) система скажет что место занято и надо выбрать другое место и повторно выполнить заполнение данных - то это уже лучше не комментировать.

Перенося ситуацию на редактирование записи БД - мы получаем, что чем раньше пользователь получит информацию о не возможности выполнения запрошенной операции - тем лучше. В идеале - еще до того как он успеет выполнить какую-либо работу по изменению. Т.е. при попытке начать изменение редактируемой записи. А это уже pessimistic concurrency control. И мы вернулись к тому, с чего начали ... ;)
Make Clarion Great Again ! 😎
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

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

Сообщение Shur »

Гм. Представьте, что пользователи захотели выбрать одно и то же место, а вы используете стратегию pessimistic concurrency control, тогда, чтобы заблокировать эту запись, пользователи конкурируют друг с другом. Хорошо, первый успевает заблокировать раньше (или СУБД назначила его победителем, не важно!), что вы скажете второму? Вы скажете "Извини, друг, но кто-то успел раньше", а это и есть opimistic concurrency control. ...и мы вернулись к тому, чем закончили :)

P.S.
А вот если после выполнения некого объема работы (ввода всей информации о пассажире, его паспорте и т.д.) система скажет что место занято и надо выбрать другое место и повторно выполнить заполнение данных - то это уже лучше не комментировать.
А так и бывает на сайте rzd.ru. Не пробовали брать билеты в разгар сезона? Плохо это или хорошо, не могу сказать. Досадно, это точно, но билеты нужнее.
Последний раз редактировалось Shur 27 Февраль 2015, 20:53, всего редактировалось 1 раз.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

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

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

Абсолютно верно ! Мы скажем второму пользователю "извини, но кто-то успел раньше".

Но только сделаем это ДО ТОГО, как пользователь начал делать работу (заполнение данных для покупки места),
а не ПОСЛЕ ТОГО как он проделал эту работу и теперь должен все начать делать сначала. Вот и вся разница.
Здесь важно в каком месте мы готовы сообщить о не возможности выполнения запрошенной операции.

С точки зрения логики бизнес-процесса нет разницы: в любом случае будет продан только один билет на место.
А вот с точки зрения пользователя - разница огромная. И чем больше он выполнит (и потеряет) работы - тем хуже.

Да, есть перестраховка. Существует вероятность, что первый пользователь откажется от покупки, а второго мы не пустили.
Но как говорится, лучше не обещать, чем обещать и не жениться. :idied:

P/S: Постоянно беру билеты на сайте RZD - я там почетный клиент, с бонусами и т.д. :)
Сначала выбор места, бронь, идентификация покупателя, оплата.
И только после выбора места я могу получить сообщение о том, что места уже нет, если выбор пройден - значит оно мое. :cat:
Make Clarion Great Again ! 😎
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

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

Сообщение Shur »

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

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

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

Проверил. Здесь боевая ничья. :)
Выбор места и данные пассажира вводятся в одном окне и потом нажимается кнопка ПРОДОЛЖИТЬ, после чего и производится бронирование места до его оплаты.
Фишка в том, что место вообще можно не выбирать - система сама его определит из свободных в ранее выбранном вагоне.
Make Clarion Great Again ! 😎
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5239
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 12 раз
Поблагодарили: 65 раз

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

Сообщение finsoftrz »

Я поддерживаю тот подход, который описал Игорь. У нас системная таблица регистрации редактируемых объектов содержит идентификатор записи и наименование таблицы. Когда пользователь открывает документ или элемент справочника на редактирование, то в эту таблицу делается запись, когда закрывает, то удаляется. Если во время редактирования другой пользователь пытается открыть на редактирование этот же документ (элемент справочника), то ему выдается сообщение, кто уже редактирует, и предлагается открыть в режиме только просмотра.
В случае аварийного отвала пользователя, который редактирует документ, запись в таблице регистрации остается до его повторного подключения. Можно просматривать, кто какие документы (справочники) редактирует и административно удалять повисшие
записи в таблице регистрации (только для тех пользователей, которые не активны в системе).
Весь этот функционал подключается автоматически на уровне шаблонов. Для документов с многострочными частями логическая блокировка выставляется только на заголовок. Есть, конечно, еще права на просмотр, редактирование, редактирование чужих записей.
Shur писал(а): Теперь по сути разразившегося скандала. Хорошо, теперь рассмотрим карточку клиента. Вы как храните адрес? Единственным полем? Это не совсем хорошо. Лучше иметь справочник адресов, а в карточке выводить список толкько тех, которые привязаны к данному клиенту, да ещё с указанием физический ли это адрес или юридический, активный/неактивный, а может у этого клиента есть дополнительные точки доставки, так это тоже всё здесь. Поэтому, если бухгалтер решит поменять реквизиты клиента, то он никак не нарушит работу всего остального офиса -- лишь бы он успел к тому моменту, когда будут напечатаны накладные.
У нас в карточке контрагента хранится юридический и фактический адреса, а также есть возможно вводить описание проезда. Определять точки доставки в отдельном справочнике адресов, на мой взгляд, не очень целесообразно. Я предпочитаю на каждую точку доставки вводить отдельного контрагента, наравне с основным покупателем. Далее возможны две ситуации. Если расчеты ведутся с основным покупателем, то в накладной указываем его в покупателе, а точку доставки в грузополучателе. В платежных документах фигурирует основной покупатель. Если расчеты ведутся с каждой точкой доставки отдельно, то в накладных она указывается в качестве покупателя. В платежных документах так же фигурирует точка доставки. Чтобы иметь в этом случае возможность видеть общие взаиморасчеты (наряду с расчетами по каждой точке доставки), в справочнике контрагентов точки доставки можно привязать к основному покупателю.
Такой подход достаточно универсален и позволяет определять условия работы для каждой точки доставки, не дублируя функционал работы с контрагентами.
Shur писал(а): Теперь про место доставки товаров. Вы его конечно же должны прошить в накладную, ведь адресов, как я уже сказал, может быть несколько у клиента. Только место доставки пробивается в накладную в момент её создания. А кладовщик, если и может поменять этот адрес, то скорее всего позже того, как накладная отправлена на склад, и ничего в ней уже менять никому нельзя за исключением этого самого кладовщика. За этим могут следить статусы сборки накладной. Так что сотрудники в редактировании накладных разводятся как по полям, так и по времени при помощи контроля статусов.
Так же используем статусы документов. Это отдельная таблица, записи которой привязаны к конкретным документам. Некоторые статусы могут устанавливаться автоматически, например, при печати конкретных форм. По примеру - честно говоря, это несколько странно, когда кладовщик меняет адрес доставки. Это не его функция.
Shur писал(а): Про розовые очки я бы не стал говорить. Всё-таки у многих из нас есть опыт работы в торговых фирмах по многу лет. И надеюсь, что сравнение concurrency check с унитазом будет дезавуировано -- он вам точно ничем не помешал, скорее вы не сумели его для себя приспособить.
Я тоже не вижу смысла использовать этот механизм.
C6/C12, ШВС, tps/btrieve.
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

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

Сообщение Shur »

Я тоже не вижу смысла использовать этот механизм.
Не обижайтесь, но по этой причине я не стал бы рекомендовать вашу программу кому-либо. Здесь дело вкуса и предпочтений -- не люблю, когда пользователя в чём-то ограничивают.
Я предпочитаю на каждую точку доставки вводить отдельного контрагента, наравне с основным покупателем.
Как только прочитал это, подумал, как же вы дебиторку-то считаете. Но, OK, разъяснили потом.

Всё же, мне кажется, надо быть поближе к природе -- "юрики" отдельно, адреса доставок отдельно,
другими словами не стоит придумывать какие-то суррогаты, там, где их быть не должно.
Иначе есть шанс поймать проблемы на ровном месте. Например, непонятно при такой архитектуре, есть ли у вас автоматическая/автоматизированная разноска платежей (авансовых или любых) по накладным.
В одном месте вы себе труд облегчили, тем самым усложнив в другом.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5239
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 12 раз
Поблагодарили: 65 раз

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

Сообщение finsoftrz »

Shur писал(а):
Я тоже не вижу смысла использовать этот механизм.
Не обижайтесь, но по этой причине я не стал бы рекомендовать вашу программу кому-либо. Здесь дело вкуса и предпочтений -- не люблю, когда пользователя в чём-то ограничивают.
Имеется ввиду, что два пользователя не могут одновременно редактировать один документ? Я думаю, что это нормальная стратегия, принятая в большинстве учетных систем. В 1с предприятии, например, из наиболее известных.
Shur писал(а):
Я предпочитаю на каждую точку доставки вводить отдельного контрагента, наравне с основным покупателем.
Как только прочитал это, подумал, как же вы дебиторку-то считаете. Но, OK, разъяснили потом.

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

Чтобы не возникало неправильных предположений, многие моменты по технологии можно посмотреть здесь:
http://www.finsoftrz.ru/index.php?page=educ
Там же можно скачать программу. Пока она в открытом доступе, но, скорее всего, скоро скачивание будет ограничено в связи с меняющейся маркетинговой политикой.
C6/C12, ШВС, tps/btrieve.
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

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

Сообщение Shur »

Ну если вы внимательно прочитали тему, то здесь никто не спорит, что pessimistic concurrency control нормальная стратегия, но мне такие не нравятся. Я и сам таких писать бы не стал, и другим бы не стал советовать. Причину объяснял выше, она всё та же -- user-friendly interface.

Об одном только прошу, не надо здесь заниматься манипуляциями. Это я про "большинство учётных систем". Откуда взяли такую статистику и с какими системами знакомы?
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

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

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

Shur писал(а): Я и сам таких писать бы не стал, и другим бы не стал советовать.
Предлагаю подвести итог нашего обсуждения. На мой взгляд очевидны две вещи.

1. Любая стратегия многопользовательского доступа зрения имеет право на жизнь, и хорошо, что есть выбор.
2. Жизнь обычно сама учит теоретиков программирования и конг-фу. Я здесь уже не нужен. ;)
Make Clarion Great Again ! 😎
Ответить