И снова про блокировки

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

Модератор: kdv

Ответить
Bizquit
Сообщения: 2
Зарегистрирован: 16 дек 2005, 11:58

И снова про блокировки

Сообщение Bizquit » 19 дек 2005, 13:51

Господа! Извиняюсь если эта тема слишком часто поднимается. У меня внешка очень слабая, по этому не могу лазить по всему форуму в поисках такой же темы :? Если данный метод гдето описывался, буду признателен за сцылку.
Требуется Ваше мнение о целесообразности метода приведенного ниже в общем виде:

За раннее скажу: метод игнорирует блокировки "отвалившихся" пользователей.

Есть таблица запросов-ответов:
SYS_REQUESTS
1. ID - integer
2. REQ_ID - integer
3. REQ_TYPE - integer
4. SENDER - varchar(80)
5. OP1 - integer
6. OP2 - integer
7. OP3 - varchar(80)
8. OP4 - varchar(80)

REQ_TYPE - тип зароса. Если NOT NULL - это запрос, если NULL - это ответ на запрос REQ_ID.
SENDER - имя пользователя который послал запрос/ответ
Ограничение: несколько пользователей с одним именем (добавлено 20.12.05) не могут работать в системе одновременно.
OPX - поля-операнды...

Сюда постятся запросы, и ответы на них. При постинге запроса/ответа срабатывает тригер и по значению поля REQ_TYPE кидает EVENT'ы (например 6 = REQ_IS_USER_BLOCKING, ответ - ANSW_IS_USER_BLOCKING, ). Все клиенты разумеется на них подписаны.

Далее.

Есть таблица блокировок.
SYS_BLOCKS
1.ID - integer
2.BLOCK_OWNER -
3. TABLE
4. REC_ID
Можно еще и дату со временем впихнуть. Не важно.

Перед блокировкой записи проверяется таблица SYS_BLOCKS. Если нужная запиь не заблокирована - блокируем регистрацией в таблице блокировок. Если заблокирована - постим риквест

например:

INSERT INTO SYS_REQUESTS
( ID, REQ_TYPE, SENDER, OP3, OP4, OP1)
VALUES (1, 6, 'SYSDBA', 'OTHER_USER', 'SomeTable', 999)

Что это значит: Юзер SYSDBA спрашивает юзера OTHER_USER на предмет наличия блокировки записи 999 в таблице Sometable

Тригер генерит Ивент IS_USER_BLOCKING и отправляет ВСЕМ.
Каждый клиет отрабатывает это поиском запроса этого типа адресованное ему. Если находит - постит ответ: держит он запись или нет

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

В общем виде все. Возможно несколько сумбурно. Пардоньте :)
Можно конечно наворотить динамически подписываемыми/создаваемыми ивентами и пр. Пока не важно. Интересно на сколько этот метод блокировки ЦЕЛЕСООБРАЗЕН? Может кто делал аналогичное. Какие если есть "подводные камни"?
Последний раз редактировалось Bizquit 20 дек 2005, 05:37, всего редактировалось 1 раз.

Bizquit
Сообщения: 2
Зарегистрирован: 16 дек 2005, 11:58

Сообщение Bizquit » 20 дек 2005, 05:46

AlexandrS писал(а):Может поможет: http://ibase.ru/devinfo/pslock.htm
AlexandrS, спасибо. Разумеется я уже читал эту статью. Там описываются принципиально другие методы. А меня интересует именно этот.

VictorIn
Сообщения: 26
Зарегистрирован: 25 мар 2005, 22:16

Re: И снова про блокировки

Сообщение VictorIn » 22 дек 2005, 06:36

Bizquit писал(а):Может кто делал аналогичное. Какие если есть "подводные камни"?
Вот посмотри этот топик http://forum.ibase.ru/phpBB2/viewtopic.php?t=1460
- немного схожая задача.

Основные грабли связанны с таблицей блокировок,
а именно наличие в ней неактуальных записей отвалившихся пользователи.
(Хотя ты пишешь, что твой метод игнорирует блокировки "отвалившихся" пользователей – непонятно это функция метода или его свойство).

В топике предлагают два варианта решения этой проблемы:
Первый состоит в том, что надо создать еще одну доп. табличку c PK для идентификаторов блокировок и ее не коммитить,
т.е. устроить там псевдо грязное чтение с использованием свойств PK (его уникальность).
Второй метод предполагает использование UDF, которая вычисляет отвалившихся пользователей по процессам на сервере.
Но этот вариант только для CS.

Ответить