В моем понимании ограничения должны обычно проверяться в конце транзакции.
Итак, в простом примере, где у нас есть одна таблица A
с единственным столбцом P
, который является ее основным ключом и таблицей B
с первичным ключом P
и внешним ключом F
для A.P
, должно работать следующее (для пустых таблиц):
begin
insert into B (P, F)
values (1, 1);
insert into A (P)
values (1);
commit;
end;
Однако Oracle выдает ошибку (на немецком языке):
[23000][2291] ORA-02291: Integritäts-Constraint (DATABASE.AB_constraint) verletzt - übergeordneter Schlüssel nicht gefunden
ORA-06512: in Zeile 3
Position: 0
, что означает Нарушено ограничение целостности - указанный ключ не найден . Если я переверну порядок
begin
insert into A (P)
values (1);
insert into B (P, F)
values (1, 1);
commit;
end;
, он будет работать нормально. Не подтверждены ли ограничения в конце транзакции в Oracle? И если да, то есть ли способ обеспечить такое поведение?
В Oracle документах указано, что (в соответствии со свойствами A C ID)
[t] транзакция переводит базу данных из одного согласованного состояния в другое согласованное состояние.
Таким образом, можно ожидать, что промежуточные состояния не обязательно должны быть последовательным. Это, безусловно, относится к примеру Oracle: деньги переводятся с одного счета на другой, в то время как общая сумма денег не совпадает (не соответствует), так как деньги были сняты с одного счета, но еще не добавлено к другому. Так почему же это не похоже на ограничения внешнего ключа?