Начиная с (по моему) Oracle 8i можно откладывать проверку целостности для ограничений до конца транзакции.
По умолчанию ограничения создаются immediate (not deferred) с немедленной проверкой целостности (не отложенное). В этом случае проверка происходит сразу после каждого запроса.
Пример: update1…; update2…; update3…; commit;
Проверка происходит после каждого update. Если происходит ошибка например при update2 то происходит откат (rollback) всей транзакции, т.е. и update1 откатиться.
Для отложенного ограничения (deferred) проверка происходит только в конце транзакции, т.е. в данном примере при выполнении commit. Если происходит ошибка, например при update2 то так же происходит откат (rollback) всей транзакции.
Разница при возникновении ошибки в том что для immediate откатятся update1 и update2, а для deferred откатятся update1, 2 и 3, т.к. update3 выполниться несмотря на ошибку в update2, т.к. проверка только в самом конце транзакции.
Если ограничение порождает какое-нибудь действие (например delete cascade), это действие выполняется как часть запроса который породил это действие.
Состояние ограничения | Проверка | |
---|---|---|
NOT DEFERRABLE | (не имеет смысла) | После каждого запроса |
DEFERRABLE | INITIALLY IMMEDIATE | После каждого запроса |
INITIALLY DEFERRED | В конце транзакции |
Состояние DEFERRABLE или NOT DEFERRABLE задается при создании ограничения и изменить его можно только пересоздание ограничения.
Для DEFERRABLE ограничений можно менять INITIALLY DEFERRED или INITIALLY IMMEDIATE с помощью:
ALTER TABLE <tab_name> MODIFY CONSTRAINT <constraint_name> INITIALLY DEFERREDINITIALLY IMMEDIATE;
или
SET CONSTRAINTS ALL IMMEDIATEDEFERRED;
SET CONSTRAINT <constraint_name>, <constraint_name> ALL IMMEDIATEDEFERRED;