Итак, мы ищем способ применения ограничений, охватывающих несколько таблиц.
Мы натолкнулись на эту старую запись в блоге , которая предлагает:
Создать материализованное представление для выбора данных, которые нарушают желаемое ограничение. MV должен быть определен с помощью REFRESH COMPLETE ON COMMIT
, чтобы он обновлялся до конца транзакции.
Создайте проверочное ограничение для материализованного представления, которое всегда оценивается как FALSE - например, CHECK (1=0)
Вот и все. Всякий раз, когда базовые таблицы обновляются, материализованное представление обновляется. Если обновление нарушает правило, то строка будет вставлена в материализованное представление; но проверочное ограничение на MV запрещает любые вставки в него, и поэтому транзакция завершается неудачей.
И хотя существуют некоторые вопросительные знаки производительности, идея звучит достаточно разумно.
Однако, postgresql - насколько нам известно - не поддерживает что-то вроде REFRESH ON COMMIT
.
Что мы можем, конечно, сделать, это установить триггеры на таблицы, которые формируют представление, которое вызовет refre sh при обновлении / удалении / вставке.
Но это может не только означать необходимость выполнения refre sh для каждой из задействованных таблиц, мы также могли долго завершать транзакцию к тому времени, когда refre sh выполняется.
Возможно, мы могли бы что-то сделать с блокировкой, но тогда возникает проблема с блокировкой правильной вещи достаточно быстро, что звучит как ужасная идея.
Так что-то есть? мы можем сделать, или нам лучше забыть об этом?
Что ближе всего к поведению "refre sh before commit"?