Блокировка строк на изменение и вставку

publexus
Дата: 27.11.2009 10:40:45
Возник такой вопрос. Допустим есть таблица
T(id int not null primary key, name varchar2(10), status char(1))
и я блокирую записи для последующего изменения:
select * from t where status='a' for update
Но это, как известно, не будет запрещать другим пользователям вставлять записи с status='a'. Можно ли сделать так, чтобы до конца моей транзакции другие сессии блокировались при попытке изменения не только существующих строк со status='a', но и вновь вставляемые с этим же статусом, или же придется блокировать всю таблицу целиком в эксклюзивном режиме?
+!+
Дата: 27.11.2009 10:43:09
а к чему такие жестокии ограничения??
publexus
Дата: 27.11.2009 10:59:16
+!+
а к чему такие жестокии ограничения??

В общем там довольно сложный алгоритм, но если уж совсем упрощенно: в таблице находятся записи сущностей, есть также определенный довольно сложный список алгоритмов уникальностей этих сущностей, список уникальностей постоянно изменяется и поэтому они реализованы программно. Следовательно, программа перед вставкой новой сущности должна проверить нет ли такой в уже в таблице по этим алгоритмам и вставить ее. А чтобы не возникла ситуация вставки другим процессом подобной сущности, можно просто заблокировать изменение или вставку небольшой пачки сущностей по соотвствию некоторого набора столбцов, которые в пределах уникальности будут постоянными. Не знаю, понятно тут что-нибудь, но суть первого вопроса это не меняет.
AlexFF__|
Дата: 27.11.2009 11:03:11
Dbms_Lock.ALLOCATE_UNIQUE
-2-
Дата: 27.11.2009 11:04:30
publexus,

Может так:
user_lock.request('Не вставляй в Ж свой статус А') в твоей транзакции и в триггере на вставку when new.status = 'A'
-2-
Дата: 27.11.2009 11:18:26
publexus
довольно сложный список алгоритмов уникальностей этих сущностей, список уникальностей постоянно изменяется
А что делать, если критерии уникальности одного процесса отличаются от критериев другого, особо, если одно пересекается с другим.
Типа надо делать процедуру, которая умеет проверять новый объект на соответствие активным блокировкам из других сессий. Например одна блокировка установлена на условие X > 5, вторая на X < 10. Приходит объект с X = x1, тут же X = x2... И устанавливать несколько блокировок (ну или поочереди). И тут, бац - вторая смена ... алгоритмов.
publexus
Дата: 27.11.2009 11:24:14
-2-
если критерии уникальности одного процесса отличаются от критериев другого

Такого не произойдет, алгоритм зашиваются в модуль и обновляется на сервере, все пользователи пользуются копиями одной и той же программы запускаемой на сервере.
select *
Дата: 27.11.2009 11:54:18
publexus
select * from t where status='a' for update
Хорошо подумай над необходимостью использовать именно select *
serpv
Дата: 27.11.2009 12:10:28
а может вместо блокирования таблицы целиком будет эффективнее использовать триггер проверки уникальности сущностей?
с учетом faq, конечно.
publexus
Дата: 27.11.2009 12:33:34
select *
publexus
select * from t where status='a' for update
Хорошо подумай над необходимостью использовать именно select *

На самом деле в данном случае на практике я этот select не использую, потому что в нем нет смысла - он никак не защитит мое приложение, я привел его к слову, так сказать, как псевдопример.