Блокировка записи

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
Дементьев Александр
Сообщения: 4
Зарегистрирован: 17 сен 2005, 21:41

Блокировка записи

Сообщение Дементьев Александр » 17 сен 2005, 22:16

Доброго времени суток!
Суть проблемы: Есть мастер таблица, к которой подключено N дочерних. Изменения в дочених таблицах влекут некоторые изменения в главной. Необходимо запретить доступ к данным в главной таблице после начала её изменения. В BDE на Paradox делал так:MainTable.Edit, и при попытке другого приложения сделать тоже,
получал ошибку типа "Record already locked", чем запрещал доступ к записи, по окнчании редактирования запись соответственно становилась доступной.Вообщем надо тоже самое.
Установлено: IB ver 5.5 и Delphi 7.

Дементьев Александр
Сообщения: 4
Зарегистрирован: 17 сен 2005, 21:41

Сообщение Дементьев Александр » 18 сен 2005, 00:44

Бутылка пива, и ответ я нашел сам
Последний раз редактировалось Дементьев Александр 18 сен 2005, 16:32, всего редактировалось 3 раза.

joolio
Сообщения: 31
Зарегистрирован: 09 июл 2005, 14:23

Сообщение joolio » 18 сен 2005, 12:13

Бутылка пива, и ответ я нашел сам
Ну так поделись!

Дементьев Александр
Сообщения: 4
Зарегистрирован: 17 сен 2005, 21:41

Сообщение Дементьев Александр » 18 сен 2005, 16:29

Значит так: в главную таблицу добавляешь поле типа:In_Use Integer
на серваке создаешь ХП (хранимую процедуру) с 2 входными и одним выходным параметром такого плана:

CREATE PROCEDURE CHECK_XXX
(ID1 INTEGER, - ID которое надо заблокировать
ID2 INTEGER - значение которое надо записать в In_Use в моём случае ID некоторого пользователя
)
RETURNS (IDU INTEGER)- возвращаем значение поля In_Use
AS
begin
select in_use from XXX
where id_XXX= :ID1 / проверяем запись на серваке на предмет того, что кто-то уже успел
into: IDU; / блокировать запись до нас, результат в IDU
if (:IDU=0) then / если запись не блокирована, то блокируем её
begin
update XXX
set in_use= :ID2
where id_XXX= :ID1;
end
suspend;
end

В Delphi делаем так:
в компонент (я использовал TIBQuery назвал spAccess) пишем SQL: select * from check_XXX(:IDA,:IDU)
кнопка работает так:
...
spAccess.Active:=false;
spAccess.Params[0].AsInteger:=XXX_ID.Value;// присваеваем ID записи
spAccess.Params[1].AsInteger:=XXX_ID_User;// тоже для пользователя
spAccess.Active:=true;// запускаем
trMain.CommitRetaining;// подтверждаем
// если не ноль, то запись блокирована
if spAccess.Fields[0].AsInteger<>0 then application.MessageBox('Запись блокирована','',MB_OK+MB_ICONERROR);
spAccess.Active:=false;
Все работает в пределах одной транзакции
При возникновении ошибки типа: deathlock смотри настройки IBTransaction
Разблокировку в пределах одного триггера пока не написал,
но думаю смысл понятен. Пишите если не работает, а если работает сообщи на форум. Кстати на этом сайте нашел по этому вопросу
хорошую статью: http://www.ibase.ru/devinfo/pslock.htm

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

Сообщение kdv » 19 сен 2005, 09:55

IB 5.5 снеси и поставь IB 5.6. А то не ровен час...

Alexey Kovyazin
Сообщения: 15
Зарегистрирован: 25 окт 2004, 19:13

Сообщение Alexey Kovyazin » 23 сен 2005, 22:15

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

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

Поэтому все же классический подход, описанный в http://www.ibase.ru/devinfo/pslock.htm, все же лучше, так как требует лишь правильно организовать транзакции и обработку ошибок.

С уважением,
Алексей Ковязин

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 23 сен 2005, 23:10

Alexey Kovyazin писал(а): Поэтому все же классический подход, описанный в http://www.ibase.ru/devinfo/pslock.htm
Алексей Ковязин
Эть, приятно, Лёшик, що вспомнил старика :) Тут, панимаш, всё прогрессивное человечество празднует в один день:

а) день рожденья Лужкова
б) рождество Пресвятой Богородицы
в) хрензнаескольколетие Куликовской битвы
г) моё 51-однолетие

ни на одной программерской тусовке не вспомнили, а вот на авто ру в полный рост :)) Ну, хоть статья к слову пришлась, знач всё на свете было не зря, не напрасно было (С) :) Ззиняюсь, пьян, ДК, режь нафик :-D

sag
Сообщения: 116
Зарегистрирован: 02 ноя 2004, 11:42

Сообщение sag » 23 сен 2005, 23:32

Merlin писал(а):Тут, панимаш, всё прогрессивное человечество празднует в один день:
а) день рожденья Лужкова
.......
я в данный момент отмечаю пятницу+осеннее равнодевств+красотищщу осеннюю..... А тут оказзываецца
Merlin писал(а): г) моё 51-однолетие

ни на одной программерской тусовке не вспомнили, а вот на авто ру в полный рост :)) Ну, хоть статья к слову пришлась, знач всё на свете было не зря, не напрасно было (С) :) Ззиняюсь, пьян....
Поздравляю! Желаю здоровья и всего!

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 24 сен 2005, 01:08

Merlin писал(а):Эть, приятно, Лёшик, що вспомнил старика :) Тут, панимаш, всё прогрессивное человечество празднует в один день:

а) день рожденья Лужкова
б) рождество Пресвятой Богородицы
в) хрензнаескольколетие Куликовской битвы
г) моё 51-однолетие
Нет, ну ведь есть что-то в нумерации латинскими буквами (a,b,c...) :wink:
Merlin писал(а):ни на одной программерской тусовке не вспомнили, а вот на авто ру в полный рост :)) Ну, хоть статья к слову пришлась, знач всё на свете было не зря, не напрасно было (С) :) Ззиняюсь, пьян, ДК, режь нафик :-D
Какой - режь ?
Поздравляем :!:
Афтар - пеши исчо 8) :!:

Ответить