Блокировка записи
Модератор: kdv
-
- Сообщения: 4
- Зарегистрирован: 17 сен 2005, 21:41
Блокировка записи
Доброго времени суток!
Суть проблемы: Есть мастер таблица, к которой подключено N дочерних. Изменения в дочених таблицах влекут некоторые изменения в главной. Необходимо запретить доступ к данным в главной таблице после начала её изменения. В BDE на Paradox делал так:MainTable.Edit, и при попытке другого приложения сделать тоже,
получал ошибку типа "Record already locked", чем запрещал доступ к записи, по окнчании редактирования запись соответственно становилась доступной.Вообщем надо тоже самое.
Установлено: IB ver 5.5 и Delphi 7.
Суть проблемы: Есть мастер таблица, к которой подключено N дочерних. Изменения в дочених таблицах влекут некоторые изменения в главной. Необходимо запретить доступ к данным в главной таблице после начала её изменения. В BDE на Paradox делал так:MainTable.Edit, и при попытке другого приложения сделать тоже,
получал ошибку типа "Record already locked", чем запрещал доступ к записи, по окнчании редактирования запись соответственно становилась доступной.Вообщем надо тоже самое.
Установлено: IB ver 5.5 и Delphi 7.
-
- Сообщения: 4
- Зарегистрирован: 17 сен 2005, 21:41
Бутылка пива, и ответ я нашел сам
Последний раз редактировалось Дементьев Александр 18 сен 2005, 16:32, всего редактировалось 3 раза.
-
- Сообщения: 4
- Зарегистрирован: 17 сен 2005, 21:41
Значит так: в главную таблицу добавляешь поле типа: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
на серваке создаешь ХП (хранимую процедуру) с 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
-
- Сообщения: 15
- Зарегистрирован: 25 окт 2004, 19:13
Здравствуйте!
Данный подход не достаточно универсальный, и требует слишком много дополнительных телодвижений - процедуру, поля создавать, вызывать.
Поэтому все же классический подход, описанный в http://www.ibase.ru/devinfo/pslock.htm, все же лучше, так как требует лишь правильно организовать транзакции и обработку ошибок.
С уважением,
Алексей Ковязин
Данный подход не достаточно универсальный, и требует слишком много дополнительных телодвижений - процедуру, поля создавать, вызывать.
Поэтому все же классический подход, описанный в http://www.ibase.ru/devinfo/pslock.htm, все же лучше, так как требует лишь правильно организовать транзакции и обработку ошибок.
С уважением,
Алексей Ковязин
Эть, приятно, Лёшик, що вспомнил старикаAlexey Kovyazin писал(а): Поэтому все же классический подход, описанный в http://www.ibase.ru/devinfo/pslock.htm
Алексей Ковязин

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



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

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

Афтар - пеши исчо

