У меня есть таблица с именем LOCK
, и я хочу убедиться, что существует не более одной строки с данным именем и типом WRITE
. Хотя допускается несколько строк с типом READ
и одинаковым именем, но только если нет строки с таким же именем и типом WRITE
.
create table "LOCK"
(
"LOCK_ID" NUMBER(19,0) NOT NULL,
"NAME" VARCHAR2(255 CHAR),
"TYPE" VARCHAR2(32 CHAR),
CONSTRAINT "SYS_LOCK_PK" PRIMARY KEY ("LOCK_ID")
);
Вставка строки должна быть атомарной, например, нет запроса с последующей вставкой в зависимости от результата запроса (потому что он мог измениться за это время).
Чтобы обеспечить атомизацию, я создал триггер для проверки первоначально упомянутого условия (повышение ошибки при сбое), которое иногда заканчивается различными недопустимыми состояниями, такими как две строки WRITE
.
Если вставки выполняются последовательно, триггер работает отлично, что приводит к предположению, что вставка + триггер не является атомарным процессом, и если так, есть ли безопасный способ решить мою проблему?
Вот триггер:
create or replace trigger "LOCK_TRIGGER"
before insert on "LOCK"
referencing NEW AS NEW
for each row
declare
c integer := 0;
begin
select count(*) into c from "LOCK" where (:NEW.typ = 'WRITE' and name = :NEW.name) or (:NEW.typ = 'READ' and name = :NEW.name and typ = 'WRITE');
if (c > 0) then
raise_application_error(-20634, 'Nope!');
end if;
end;