Вставить задержку при сетевой ошибке и вставить вставку триггера в dblink-таблицу - PullRequest
1 голос
/ 01 декабря 2011

Возможно странное название, я постараюсь объяснить.У меня есть два сервера Oracle serverA и serverB.

  • На сервере A у меня есть таблица tabA, в которую каждую минуту вставляется строка.
  • На сервере B я создаю таблицу tabB, которая имеет ту же структуру, что и tabA.
  • На сервере A я создаю ссылку на сервер B.На сервере A я создаю триггер вставки, например

На A

create trigger tabA_trig
after insert on tabA
begin
insert into tabB@serverB(...) values(:new....,:new... etc);

exception
 when others then null;
end tabA_trig;

После создания этого триггера новая строка вставляется в tabB каждый раз, когда новая строка вставляется в tabA, как и ожидалось.

ОДНАКО: когда связь между сервером A и сервером B прерывается, я не получаю никаких ошибок (исключение выше позаботится об этом), НО данные также не вставляются в tabA!Очень странно, и что еще более странно, примерно через 15 минут новые данные снова вставляются в tabA.Через некоторое время пропущенные данные начинают заполнять отверстие, а через некоторое время данные отсутствуют, и вставка работает как положено.

Пример (tabA и tabB, время в первом столбце, минуты и часы, значение второго столбца):

Network OK:
tabA 1000 22;1001 22;1002 22
tabB 1000 22;1001 22;1002 22    

Network ERROR:
About 15 minutes of no new data.

After 15 minutes:
tabA 1000 22;1001 22;1002 22;1017 22;1018 22;....
tabB 1000 22;1001 22;1002 22


After 30 minutes:
tabA 1000 22;1001 22;1002 22;1003 22;1004 22;1005 22;1006 22;1017 22;1018 22;....
tabB 1000 22;1001 22;1002 22

After 1 hour:
tabA 1000 22;1001 22;1002 22;1003 22;1004 22;1005 22;1006 22;1006 22;...;1017 22;1018 22;....
tabB 1000 22;1001 22;1002 22

Если я отключу триггер, вставка в tabA сработает немедленно.

Причина, по которой я использую триггеры, а не материализованные представления, заключается в том, что я хочу сохранить все данные, которые имеютбыл реплицирован на tabB, даже если данные удалены из tabA.

Кто-нибудь знает, что с этим делать?

Ответы [ 3 ]

1 голос
/ 01 декабря 2011

Или расширенные очереди Oracle, если обе базы данных имеют одинаковые версии. Немного сложно настроить, но модель асинхронного обмена сообщениями будет обрабатывать случаи, когда одна или другая база данных не работает.

Относительно того, является ли это слишком сложным решением, я нахожу, что упрощаю вопросы, которые я здесь задаю. То, что вся проблема только ОП, может сказать. Кажется ли проблема скорее проблемой обмена сообщениями или объединения данных? Оба решения будут работать намного лучше, чем триггеры.

1 голос
/ 01 декабря 2011

Во-первых, репликация данных из одной базы данных в другую с использованием пользовательских триггеров почти наверняка является плохой идеей. Oracle предоставляет множество технологий, которые помогут вам реализовать репликацию. Материализованные представления - это, вероятно, самое простое и, скорее всего, то, что вам здесь нужно, хотя вы также можете посмотреть на Streams, Golden Gate или даже что-то вроде Change Data Capture (CDC). Пользовательские триггеры оказывают существенное влияние на производительность триггерной вставки и вводят множество сценариев отказов, таких как этот, которые трудно отлаживать.

Поскольку никакие данные не вставляются в tabA, когда сеть не работает, но эти вставки появляются позже, я склонен подозревать, что возникает какое-то исключение, которое заставляет приложение вставки ставить очередь на вставку до более поздней или что приложение создает распределенную транзакцию, которая включает в себя либо базу данных B, либо какой-либо другой ресурс, на который также влияет сетевая ошибка, которая не может быть успешно зафиксирована до некоторого более позднего момента времени. Поскольку мы ничего не знаем об архитектуре вашего приложения, трудно слишком глубоко рассуждать. Вы можете проверить таблицу DBA_2PC_PENDING, чтобы узнать, выступает ли Oracle в качестве координатора распределенных транзакций для каких-либо распределенных транзакций, но существует множество других программных компонентов, которые могут выступать в качестве координатора транзакций.

0 голосов
/ 01 декабря 2011
  1. Вам необходимо активировать обнаружение обрыва соединения, используя SQLNET.EXPIRETIME
  2. Я бы не рекомендовал репликацию так, как вы это делаете. Вы можете использовать материализованное представление «ON COMMIT REFRESH» для выполнения этого вида репликации.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...