Способы блокирования таблицы БД на чтение, удаление
Способы блокирования таблицы БД на чтение, удаление
Здравствуйте!
Подскажите пожалуйста как лучше поступить в такой ситуации:
Имеется БД(Firebird 2.1) к которой обращается до 10-и человек (может и больше, но вряд ли), каждый из своей клиентской программы. В БД хранятся данные о нескольких проектах.
Изменения, вносимые клиентом в одну запись, влияют на значения в некоторых (в зависимости от значений введенных пользователем) записях в нескольких таблицах БД.
Проблема:
Каждая клиентская программа хранит в массиве всю информацию из БД о проекте с которым работает пользователь. N пользователей могут редактировать(в окне редактора программы несколько минут) N разных записей (вероятнее всего из одного и того же проекта) одновременно.
При завершении редактирования записи программа пересчитывает значения в записях, зависящих от отредактированной, и скидывает все это в БД.
При этом, вносимые разными пользователями в разные записи изменения могут влиять на одни и те же записи таблиц БД.
Соответственно: последний завершивший редактирование может отменить изменения внесенные в БД теми кто закончил редактирование раньше.
Было найдено такое логическое решение данной проблемы:
Чтобы записи, зависящие от редактируемой, не оказались удалены пока пользователь редактирует задачу - требуется запретить удаление записей из БД на время редактирования.
На случай, если во время редактирования в БД кем-то были внесены новые записи или были изменены старые, программа перечитывает БД.
После этого чтобы никто больше не прочитал устаревшую информацию - требуется заблокировать БД(некоторые таблицы) на чтение.
Только после этого происходит пересчет в программе и запись в БД.
Остается вопрос:
Как решить это средствами БД?
1. Возможно ли обойтись средствами БД?
2. Если создать таблицу с состоянием БД: разрешено(запрещено) читать(удалять), то как обойти ситуацию когда клиент отключился не сняв выставленный собой запрет?
Я не очень хорошо знаком с базами данных и Firebird в частности, но с радостью почитаю документацию(в тч и на английском), если вы посоветуете что-то по даным вопросам. Если непонятно описал ситуацию - спрашивайте.
Читал вот это: Транзакции в InterBase и Firebird, Как заблокировать запись в InterBase/Firebird. Как я понял там подразумевается блокировка небольшого числа записей, мне требуется блокировать до нескольких тысяч записей, а лучше таблицу целиком. Если не прав, и там есть решение, подскажите как это применить к данной ситуации.
Заранее спасибо!
Подскажите пожалуйста как лучше поступить в такой ситуации:
Имеется БД(Firebird 2.1) к которой обращается до 10-и человек (может и больше, но вряд ли), каждый из своей клиентской программы. В БД хранятся данные о нескольких проектах.
Изменения, вносимые клиентом в одну запись, влияют на значения в некоторых (в зависимости от значений введенных пользователем) записях в нескольких таблицах БД.
Проблема:
Каждая клиентская программа хранит в массиве всю информацию из БД о проекте с которым работает пользователь. N пользователей могут редактировать(в окне редактора программы несколько минут) N разных записей (вероятнее всего из одного и того же проекта) одновременно.
При завершении редактирования записи программа пересчитывает значения в записях, зависящих от отредактированной, и скидывает все это в БД.
При этом, вносимые разными пользователями в разные записи изменения могут влиять на одни и те же записи таблиц БД.
Соответственно: последний завершивший редактирование может отменить изменения внесенные в БД теми кто закончил редактирование раньше.
Было найдено такое логическое решение данной проблемы:
Чтобы записи, зависящие от редактируемой, не оказались удалены пока пользователь редактирует задачу - требуется запретить удаление записей из БД на время редактирования.
На случай, если во время редактирования в БД кем-то были внесены новые записи или были изменены старые, программа перечитывает БД.
После этого чтобы никто больше не прочитал устаревшую информацию - требуется заблокировать БД(некоторые таблицы) на чтение.
Только после этого происходит пересчет в программе и запись в БД.
Остается вопрос:
Как решить это средствами БД?
1. Возможно ли обойтись средствами БД?
2. Если создать таблицу с состоянием БД: разрешено(запрещено) читать(удалять), то как обойти ситуацию когда клиент отключился не сняв выставленный собой запрет?
Я не очень хорошо знаком с базами данных и Firebird в частности, но с радостью почитаю документацию(в тч и на английском), если вы посоветуете что-то по даным вопросам. Если непонятно описал ситуацию - спрашивайте.
Читал вот это: Транзакции в InterBase и Firebird, Как заблокировать запись в InterBase/Firebird. Как я понял там подразумевается блокировка небольшого числа записей, мне требуется блокировать до нескольких тысяч записей, а лучше таблицу целиком. Если не прав, и там есть решение, подскажите как это применить к данной ситуации.
Заранее спасибо!
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Re: Способы блокирования таблицы БД на чтение, удаление
И в чём проблема? Может у него как раз данные правильные, а у тех, кто закончил редактирование раньше - нет. Соответственно отменить внесённые в БД неправильные данные - правильное поведение.Соответственно: последний завершивший редактирование может отменить изменения внесенные в БД теми кто закончил редактирование раньше.
Re: Способы блокирования таблицы БД на чтение, удаление
К сожалению нет, все участники редактирования равноправны и данные(локальные) правильные у всех. Только если кто-то один уже внес свои изменения в БД, то все другие должны узнать о них и пересчитать свою локальную версию данных в массиве в соответствии ними и теми что вносят сами, прежде чем записать свою версию в БД.Dimitry Sibiryakov писал(а):Может у него как раз данные правильные, а у тех, кто закончил редактирование раньше - нет. Соответственно отменить внесённые в БД неправильные данные - правильное поведение.
В противном случае: если переписывать только то что изменилось, одни записи будут соответствовать одной ситуации, а другие другой. Или, если переписывать все данные целиком, то чьи-то изменения будут потеряны полностью. А каждое изменение это результат размышлений, сопоставлений и согласований и совершать эти действия вновь никто не захочет.
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Re: Способы блокирования таблицы БД на чтение, удаление
То есть данные у всех разные, но при этом все правильные? И записываются в одно место?
Или всё таки измените структуру данных так, чтобы разные правильные данные хранились в разных местах и таким образом не пересекались.
Ну так обрабатывайте конфликт при update (RTFM транзакции).Только если кто-то один уже внес свои изменения в БД, то все другие должны узнать о них и пересчитать свою локальную версию данных в массиве в соответствии ними и теми что вносят сами, прежде чем записать свою версию в БД.
Или всё таки измените структуру данных так, чтобы разные правильные данные хранились в разных местах и таким образом не пересекались.
Re: Способы блокирования таблицы БД на чтение, удаление
Данные у всех разные только в тот момент когда они закончили редактирование записи, произошел пересчет данных, но изменения еще не записаны в БД. После того как изменения внесены в БД, каждый должен пересчитать свою версию в соответствии с ними.
Re: Способы блокирования таблицы БД на чтение, удаление
не отменить а заменить, переписать. Это нормально и естественно, если только при обновлении данных НЕ проверяется что было в них раньше.последний завершивший редактирование может отменить изменения внесенные в БД теми кто закончил редактирование раньше.
Поищите информацию например по UpdateMode - upWhereKeyOnly, upWhereAll, upWhereChanged (информация есть здесь http://www.ibase.ru/devinfo/bde.htm , а например у IBDataSet это регулируется текстами запросов update)
про блокировку записей написано тут
http://www.ibase.ru/devinfo/pslock.htm
Вам надо сначала подумать, как Вы это хотите сделать событийно. Т.е. теоретическая последовательность действий. Если хотите чтобы обновления шли последовательно - это одно, тут можно блокировать таблицы на запись (www.ibase.ru/devinfo/ibtrans.htm). Если надо чтобы не обновлялись уже измененные данные, значит надо сравнивать значения в начале редактирования и перед обновлением (см выше про UpdateMode).После этого чтобы никто больше не прочитал устаревшую информацию - требуется заблокировать БД(некоторые таблицы) на чтение.
Только после этого происходит пересчет в программе и запись в БД.
В общем, сначала Вам надо разобраться с параметрами транзакций. Вы хоть и уже почитали упомянутые мной статьи, но я советую их прочитать еще раза 4-5. Потому что желание "блокировать несколько тысяч записей" неадекватно.
Re: Способы блокирования таблицы БД на чтение, удаление
Спасибо, следую вашему совету, то же самое посоветовали на другом форуме, так что читаю...В общем, сначала Вам надо разобраться с параметрами транзакций. Вы хоть и уже почитали упомянутые мной статьи, но я советую их прочитать еще раза 4-5. Потому что желание "блокировать несколько тысяч записей" неадекватно.
Re: Способы блокирования таблицы БД на чтение, удаление
Научился блокировать доступ к таблицам на чтение и на запись для других транзакций.
Все еще читаю... многое стало понятней...
Пока задам вопрос:
Есть ли такое сочетание параметров конкурирующих транзакций, чтобы заблокировать таблицу только на удаление записей, но оставить возможность их обновления(редактирования)? Или это можно сделать только запретив созданному на сервере пользователю удаление записей?
Возможно найду ответ сам в процессе чтения, но если не найду, надеюсь на вашу помощь.
Все еще читаю... многое стало понятней...
Пока задам вопрос:
Есть ли такое сочетание параметров конкурирующих транзакций, чтобы заблокировать таблицу только на удаление записей, но оставить возможность их обновления(редактирования)? Или это можно сделать только запретив созданному на сервере пользователю удаление записей?
Возможно найду ответ сам в процессе чтения, но если не найду, надеюсь на вашу помощь.
Re: Способы блокирования таблицы БД на чтение, удаление
нет конечно. для транзакций (и для сервера) удаление - это тоже модификация. Как и для версий - delete это создание (!) версии.Есть ли такое сочетание параметров конкурирующих транзакций, чтобы заблокировать таблицу только на удаление записей, но оставить возможность их обновления(редактирования)?
Вообще модификация - это любое ИЗМЕНЕНИЕ. insert/update/delete. отдельно запрет на эти операции идет только через GRANT, для пользователей.
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Re: Способы блокирования таблицы БД на чтение, удаление
Вообще-то - есть. FK ссылка на эту таблицу позволит вставку и изменение, но не удаление.
Но с такой постановкой задачи гораздо правильнее было бы пойти на Оракул...
Но с такой постановкой задачи гораздо правильнее было бы пойти на Оракул...
Re: Способы блокирования таблицы БД на чтение, удаление
Для данной задачи решили проблему с блокировками одним разом - организовали программу так что данные в записях таблиц не зависят друг от друга. В результате блокировать таблицы целиком на какое либо действие не требуется! Но, уверен, вскоре полученные знания пригодятся.
Всем огромное спасибо!
PS: Буду и дальше учиться работать с БД, нашел несколько учебников из списка рекомендуемой литературы. Если что - обращусь за советом снова .
Всем огромное спасибо!
PS: Буду и дальше учиться работать с БД, нашел несколько учебников из списка рекомендуемой литературы. Если что - обращусь за советом снова .
Re: Способы блокирования таблицы БД на чтение, удаление
радость какая. а раньше - зависели? ужасорганизовали программу так что данные в записях таблиц не зависят друг от друга.
Re: Способы блокирования таблицы БД на чтение, удаление
Да зависели. Изменения, сделанные пользователем в одной записи, вынуждали его клиент пересчитывать данные в других записях, которые на момент записи их в БД могли редактироваться другими участниками процесса.kdv писал(а):радость какая. а раньше - зависели? ужасорганизовали программу так что данные в записях таблиц не зависят друг от друга.
В данном случае нашелся способ избежать этого, не факт, что в другом случае он тоже найдется.
Если что-то не так, расскажите что - переделаю как правильно/(изменю подход). А то непонятно в чем "ужас", даже страшно за программу стало .
Re: Способы блокирования таблицы БД на чтение, удаление
Вы уже сами все придумали и описали решение, которое Вам пришло в голову. А я бы хотел услышать что это на самом деле за задача.Если что-то не так, расскажите что - переделаю как правильно/(изменю подход).
Обычно автоматизация какого-то вида деятельности не значит, что программу нужно делать именно так, как это происходит в реальной жизни. Особенно в плане всяких блокировок, зависимых друг от друга записей, и т.п.
Re: Способы блокирования таблицы БД на чтение, удаление
Описание реальной задачи:А я бы хотел услышать что это на самом деле за задача.
Есть некий проект.
Есть люди(в пределах 10 чел.), которые его формируют:
- определяют срок выполнения,
- разбивают его на задачи и подзадачи,
- определяют срок выполнения отдельных задач, даты их начала и окончания,
- определяют последовательность выполнения задач (у задачи указываются непосредственные предшественники без которых задача не начнется),
- и еще некоторые параметры (ресурсы, процент завершенности и др.)
Требуется создать программу(клиент, обращающийся к общей БД) для совместной работы над проектом. При изменении сроков выполнения одной из задач, у некоторых задач даты начала и окончания также поменяются. Нежелательно допустить того чтобы указанные во время редактирования задачи-предшественники были удалены другими пользователями.
По сути, программа похожа на MS Project. Строит диаграммы Ганта и сетевые графики, считает ранние и поздние сроки начала и окончания и тд.
В результате: было принято решение отказаться от хранения сроков начала задач и рассчитывать их на клиенте при перечитывании БД. А с удалением указанных предшественников пришлось смириться (выводить уведомление что задачи-предшественника больше нет в проекте и сохранять без нее).
Re: Способы блокирования таблицы БД на чтение, удаление
задачи и подзадачи хранятся в виде дерева в одной таблице, или количество уровней жестко задано и задачи и подзадачи хранятся в разных таблицах?
Re: Способы блокирования таблицы БД на чтение, удаление
На данный момент(вероятно так и останется) все задачи хранятся в одной таблице. У каждой задачи, указывается родительская задача, а родительские задачи имеют отметку о том что они являются таковыми. Уровень вложенности неограничен.
Не совсем понял как хранить их в виде дерева.
Не совсем понял как хранить их в виде дерева.