Способы блокирования таблицы БД на чтение, удаление

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 04 авг 2010, 13:42

Здравствуйте!

Подскажите пожалуйста как лучше поступить в такой ситуации:
Имеется БД(Firebird 2.1) к которой обращается до 10-и человек (может и больше, но вряд ли), каждый из своей клиентской программы. В БД хранятся данные о нескольких проектах.
Изменения, вносимые клиентом в одну запись, влияют на значения в некоторых (в зависимости от значений введенных пользователем) записях в нескольких таблицах БД.

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

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


Остается вопрос:
Как решить это средствами БД?
1. Возможно ли обойтись средствами БД?
2. Если создать таблицу с состоянием БД: разрешено(запрещено) читать(удалять), то как обойти ситуацию когда клиент отключился не сняв выставленный собой запрет?

Я не очень хорошо знаком с базами данных и Firebird в частности, но с радостью почитаю документацию(в тч и на английском), если вы посоветуете что-то по даным вопросам. Если непонятно описал ситуацию - спрашивайте.
Читал вот это: Транзакции в InterBase и Firebird, Как заблокировать запись в InterBase/Firebird. Как я понял там подразумевается блокировка небольшого числа записей, мне требуется блокировать до нескольких тысяч записей, а лучше таблицу целиком. Если не прав, и там есть решение, подскажите как это применить к данной ситуации.

Заранее спасибо!

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение Dimitry Sibiryakov » 04 авг 2010, 14:15

Соответственно: последний завершивший редактирование может отменить изменения внесенные в БД теми кто закончил редактирование раньше.
И в чём проблема? Может у него как раз данные правильные, а у тех, кто закончил редактирование раньше - нет. Соответственно отменить внесённые в БД неправильные данные - правильное поведение.

samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 04 авг 2010, 14:26

Dimitry Sibiryakov писал(а):Может у него как раз данные правильные, а у тех, кто закончил редактирование раньше - нет. Соответственно отменить внесённые в БД неправильные данные - правильное поведение.
К сожалению нет, все участники редактирования равноправны и данные(локальные) правильные у всех. Только если кто-то один уже внес свои изменения в БД, то все другие должны узнать о них и пересчитать свою локальную версию данных в массиве в соответствии ними и теми что вносят сами, прежде чем записать свою версию в БД.
В противном случае: если переписывать только то что изменилось, одни записи будут соответствовать одной ситуации, а другие другой. Или, если переписывать все данные целиком, то чьи-то изменения будут потеряны полностью. А каждое изменение это результат размышлений, сопоставлений и согласований и совершать эти действия вновь никто не захочет.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение Dimitry Sibiryakov » 04 авг 2010, 14:32

То есть данные у всех разные, но при этом все правильные? И записываются в одно место?
Только если кто-то один уже внес свои изменения в БД, то все другие должны узнать о них и пересчитать свою локальную версию данных в массиве в соответствии ними и теми что вносят сами, прежде чем записать свою версию в БД.
Ну так обрабатывайте конфликт при update (RTFM транзакции).

Или всё таки измените структуру данных так, чтобы разные правильные данные хранились в разных местах и таким образом не пересекались.

samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 04 авг 2010, 14:40

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение kdv » 05 авг 2010, 00:45

последний завершивший редактирование может отменить изменения внесенные в БД теми кто закончил редактирование раньше.
не отменить а заменить, переписать. Это нормально и естественно, если только при обновлении данных НЕ проверяется что было в них раньше.
Поищите информацию например по 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. Потому что желание "блокировать несколько тысяч записей" неадекватно.

samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 05 авг 2010, 08:53

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

samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 06 авг 2010, 16:54

Научился блокировать доступ к таблицам на чтение и на запись для других транзакций.
Все еще читаю... многое стало понятней...

Пока задам вопрос:
Есть ли такое сочетание параметров конкурирующих транзакций, чтобы заблокировать таблицу только на удаление записей, но оставить возможность их обновления(редактирования)? Или это можно сделать только запретив созданному на сервере пользователю удаление записей?

Возможно найду ответ сам в процессе чтения, но если не найду, надеюсь на вашу помощь.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение kdv » 08 авг 2010, 17:20

Есть ли такое сочетание параметров конкурирующих транзакций, чтобы заблокировать таблицу только на удаление записей, но оставить возможность их обновления(редактирования)?
нет конечно. для транзакций (и для сервера) удаление - это тоже модификация. Как и для версий - delete это создание (!) версии.

Вообще модификация - это любое ИЗМЕНЕНИЕ. insert/update/delete. отдельно запрет на эти операции идет только через GRANT, для пользователей.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение Dimitry Sibiryakov » 09 авг 2010, 14:41

Вообще-то - есть. FK ссылка на эту таблицу позволит вставку и изменение, но не удаление.

Но с такой постановкой задачи гораздо правильнее было бы пойти на Оракул...

samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 10 авг 2010, 09:26

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

Всем огромное спасибо!

PS: Буду и дальше учиться работать с БД, нашел несколько учебников из списка рекомендуемой литературы. Если что - обращусь за советом снова :) .

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение kdv » 10 авг 2010, 21:35

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

samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 11 авг 2010, 14:18

kdv писал(а):
организовали программу так что данные в записях таблиц не зависят друг от друга.
радость какая. а раньше - зависели? ужас :)
Да зависели. Изменения, сделанные пользователем в одной записи, вынуждали его клиент пересчитывать данные в других записях, которые на момент записи их в БД могли редактироваться другими участниками процесса.
В данном случае нашелся способ избежать этого, не факт, что в другом случае он тоже найдется.

Если что-то не так, расскажите что - переделаю как правильно/(изменю подход). А то непонятно в чем "ужас", даже страшно за программу стало :) .

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение kdv » 12 авг 2010, 09:52

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

samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 12 авг 2010, 10:46

А я бы хотел услышать что это на самом деле за задача.
Описание реальной задачи:

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

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

По сути, программа похожа на MS Project. Строит диаграммы Ганта и сетевые графики, считает ранние и поздние сроки начала и окончания и тд.

В результате: было принято решение отказаться от хранения сроков начала задач и рассчитывать их на клиенте при перечитывании БД. А с удалением указанных предшественников пришлось смириться (выводить уведомление что задачи-предшественника больше нет в проекте и сохранять без нее).

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение kdv » 12 авг 2010, 12:08

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

samuel
Сообщения: 9
Зарегистрирован: 04 авг 2010, 12:33

Re: Способы блокирования таблицы БД на чтение, удаление

Сообщение samuel » 12 авг 2010, 12:32

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

Ответить