Форум: "Базы";
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];
ВнизIBase: блокировка доступа к редактируемой записи Найти похожие ветки
← →
Merry (2007-02-16 09:00) [0]Использую TIBDataSet для отбора всех записей из таблицы.
Когда оба пользователя находятся одновременно в режиме редактирования одной и той же записи из этой TIBDataSet, то при сохранении этой записи сохраняется вариант редактирования того клиента, который закрывает эту запись последним. Ну это понятно.
Вопрос: как показать второму клиенту, что запись находится на редактировании? Как вы решаете проблему подобного рода.
Вопрос 2: Если 2 таблицы главная и детальная, то очень удобно использовать тот же TIBDataSet. Но, если таблица главная большая (порядка 100 тысяч записей), что займёт наверное немало времени на переоткрытие TIBDataSet, то стоит попробовать TIBQuery+TIBUpdateSQL? А как в этом случае выполнить связку с детальной таблицей?
Привожу код сохранения записи:
try
TIBDataSet1.edit;
TIBDataSet1.post;
IBTransaction1.CommitRetaining;
except
TIBDataSet1.cancel;
IBTransaction1.Rollback;
exit;
end;
← →
Sergey13 © (2007-02-16 09:15) [1]> Использую TIBDataSet
Это правильно. Но что бы грамотно его использовать надо знать язык SQL хотя бы в минимальных объемах.
Например заблокировать данные можно добавив в select фразу for update. А при добавлении к тому же селекту секции where получим не 100000 таблицу, а только ту ее часть что нужна пользователю в данный момент.
← →
Sergey13 © (2007-02-16 09:17) [2]> [0] Merry (16.02.07 09:00)
Много полезного можно узнать о ИБ на сайте ibase.ru
← →
ЮЮ © (2007-02-16 09:20) [3]
> Как вы решаете проблему подобного рода.
Единствкеере решение, к которому удолось прийти самому, - пользоватнль не должен иметь доступа к записям, как к "записям таблицы БД", а лишь как к строкам документа, порождающих эти записи.
После этого, вероятность редактирования одной и той же записи двумя пользователями становится нонсенсом, ибо 1) один и тот же докумен не может оказаться в руках двух пользователей 2) роли ввода того или иного документа обычно разделены между разными пользователями. 3) введя длкумкнтам определенные статусы, например, "подписан", можно запретить редактировать его содержимое. 4) можно как минимум, не ведя доп.лога, отследить автора последних изменений
← →
Merry (2007-02-16 09:24) [4]>ЮЮ © (16.02.07 09:20) [3]
значит, всё таки надо отойти от использования TIBDataSet, а перейти к TIBQuery+TIBUpdateSQL? И работать не в DBEdit, а в Edit?
← →
Merry (2007-02-16 09:27) [5]>Sergey13 © (16.02.07 09:15) [1]
>Например заблокировать данные можно добавив в select фразу for update.
Что имеется в виду?
Я пишу для TIBDataSet: select * from table1 where Field1=:Parametr1
А где использовать for update?
← →
Sergey13 © (2007-02-16 09:33) [6]> [5] Merry (16.02.07 09:27)
А в документации посмотреть не судьба? Я ж тебе даже адрес дал, где все это описывается подробно и грамотно.
← →
ЮЮ © (2007-02-16 09:54) [7]
> значит, всё таки надо отойти от использования TIBDataSet,
> а перейти к TIBQuery+TIBUpdateSQL? И работать не в DBEdit,
> а в Edit?
Такого я не говорил.
Я говорил лишь о том, что нельзя в DBGride дать для редактирвания всю таблицу, состоящую из записей. Пользователь должен их только видеть. А редактировать через Документ, их породивший, если пользователю дано на то право.
Ибо без этого, два пользователя видят запись, которя с их точки зрения неверна (иначе откуда возникло желание у обоих её исправить). А на самом деле, один пользователь отрабатывал один документ, а другой - другой. В результате оба видят недостоверную с их точки зрения информацию и начинают править. А с точки зрения на записи со стороны документов, часто имеющих к тому же бумажный прототип, всё должно именно так и выгляеть.
← →
Виталий Панасенко © (2007-02-16 10:08) [8]А смысл всего этого ? Какая разница, когда поменяются данные: через 0,00125 секунды после того, как первый пользователь записал изменения или через 12 дней, 12 месяцев ?
← →
Desdechado © (2007-02-16 10:25) [9]Разделение полномочий - вот это выход.
Один гвоздь вдвоем не забивают. И редактировать 1 запись одновременно двое (десятеро) не должны. И решается это не интерфейсно, а на уровне логики построения приложения. ЮЮ здесь прав.
Если же ОЧЕНЬ надо сделать одновременность работы с одними данными на запись, то "кто последний, тот и папа". А там пусть на кулаках разбираются. Глядишь, и тебе достанется.
← →
Val © (2007-02-16 10:57) [10]>[8] Виталий Панасенко © (16.02.07 10:08)
потеря изменений первого, если запись на редактирование получили одновременно(одинаковую)
← →
Виталий Панасенко © (2007-02-16 14:23) [11]
> Val © (16.02.07 10:57) [10]
> >[8] Виталий Панасенко © (16.02.07 10:08)
> потеря изменений первого, если запись на редактирование
> получили одновременно(одинаковую)
Да? А что, если ПЕРВЫЙ сделал Post Commit в 13:21:01, а ВТОРОЙ начал редактировать в 13:21:05 и внес изменения в 13:21:10 В ТУ ЖЕ ЗАПИСЬ что-то поменяется ?
Вот заблокирова первый запись, второй пользователь начинает редактирование и получает отказ. Но через 5 секунд он смело может рподелать эту операцию опять...(есть там нюансы, но не существенные)
← →
Merry (2007-02-16 14:51) [12]Вопрос в том: как вообще второму клиенту при открытии записи показать, что она уже на редактировании другим клиентом? Или как при попытке сохранить эту запись сказать пользователю, что сохранение не возможно, т.к. эта запись на редактировании другим клиентом. Или вообще, может первый клиент эту запись удалил, а второй в этот же момент пытается открыть эту запись, т.к. она в его DBGride ещё присутствует. Как это всё отрегулировать?
← →
Merry (2007-02-16 14:54) [13]К сожалению, теоретически мне информация предложенная на ibase.ru понятна, но практически... нет. Так как реализую многопользовательскую БД впервые и хочется конкретных примеров, желательно с программным кодом.
← →
Val © (2007-02-16 14:54) [14]>[11] Виталий Панасенко © (16.02.07 14:23)
да. я несколько о другом писал.
А в вашем случае они получают на редактирование разные записи, последовательно - вот тогда действительно дельта пофиг и вопроса-то нет.
← →
Val © (2007-02-16 14:59) [15]>[12] Merry (16.02.07 14:51)
Надо ли ему это показывать? Если запись заблокирована другим пользователем, при попытке завершить изменения(коммит) сервер выдаст исключение - обрабатывайте и показывайте второму - "я занята, зайдите завтра..."
При попытке редактирования(вернее подтверждения изменений, поскольку данные для редактирования уже есть в клиентском кеше) удаленной записи ничего не произойдет - апдейт пройдет вхолостую,т.к. данного ид уже нет в таблице.
← →
Desdechado © (2007-02-16 15:11) [16]> реализую многопользовательскую БД впервые
Поэтому для начала найди в ТЗ необходимость (и ее обоснование) для одновременного редактирования одной записи несколькими людьми.
Ни в одном нормальном ТЗ такую необходимость никто не ставит.
А проблемы твои могут вырости из слабости формализации предметной области. Например, тебе кажется, что разные пользователи могут одновременно редактировать некий товар (один - наименование, другой - колиество на складе 1, третий - количество на складе 2 и т.п.). Если у тебя все это хранится в одной таблице (или даже в одной записи), то и появляется задаваемый тобой вопрос. Но это разные смысловые сущности, поэтому не должны храниться в одном месте (в одной таблице и в одной записи). Здесь поможет устранение причины, а не следствия.
← →
Petr V. Abramov © (2007-02-17 00:49) [17]> : как вообще второму клиенту при открытии записи показать, что она уже на редактировании другим клиентом?
select for update + обработать ошибку и выдать сообщение по-юзерски
+ внимательно прочитать посты ЮЮ ©
← →
MsGuns © (2007-02-17 01:56) [18]> как вообще второму клиенту при открытии записи показать, что она уже на редактировании другим клиентом?
Если вообще стоит такой вопрос, то логика построения интерфейса "клиент-сервер" изначально спроектирована неверно.
Что же касается самой ситуации "конфликта", то разрешать ее необходимо на уровне изолированности транзакций и, как совершенно справедливо заметил ЮЮ, концепцией проектирования объектов БД
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.046 c