Защита распределенных транзакций Oracle от сетевых сбоев - PullRequest
3 голосов
/ 23 февраля 2011

Я синхронизирую таблицу в локальной базе данных с данными из таблицы в базе данных на противоположной стороне Земли, используя распределенные транзакции. Сети подключены через vpn через Интернет. В большинстве случаев он работает нормально, но когда соединение прерывается во время активной транзакции, блокировка препятствует повторному запуску задания. Я не могу убить сеанс блокировки. Попытка сделать это просто возвращает «ORA-00031: Сеанс, помеченный для уничтожения», и он фактически не уничтожается, прежде чем я запускаю локальную базу данных.

Работа по синхронизации в основном

CURSOR TRANS_CURSOR IS    
SELECT COL_A, COL_B, COL_C    
 FROM REMOTE_MASTERTABLE@MY_LINK    
 WHERE UPDATED IS NULL;    

BEGIN    
  FOR TRANS IN TRANS_CURSOR LOOP    

    INSERT INTO LOCAL_MASTERTABLE    
      (COL_A, COL_B, COL_C)    
    VALUES    
      (TRANS.COL_A, TRANS.COL_B, TRANS.COL_C);    

    INSERT INTO LOCAL_DETAILSTABLE (COL_A, COL_D, COL_E)
      SELECT COL_A, COL_D, COL_E
      FROM REMOTE_DETAILSTABLE@MY_LINK
      WHERE COL_A = TRANS.COL_A;

    UPDATE REMOTE_MASTERTABLE@MY_LINK SET UPDATED = 1 WHERE COL_A = TRANS.COL_A;    
  END LOOP;    
END;

Будем весьма благодарны за любые идеи сделать эту синхронизирующую операцию более терпимой к отключениям сети. Я использую Oracle Standard Edition One, поэтому функции Enterprise недоступны.

ТИА Сорен

Ответы [ 2 ]

3 голосов
/ 23 февраля 2011

Прежде всего, вам действительно нужно создать собственное решение для репликации?Oracle предоставляет такие технологии, как Streams, которые позволяют надежно реплицировать изменения данных из одной системы в другую, не завися от того, что ссылка на базу данных всегда доступна.Это также сводит к минимуму объем кода, который вы должны написать, и объем обслуживания, которое вы должны выполнить.

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

1 голос
/ 23 февраля 2011

Вы можете использовать массовую обработку вместо зацикливания.Массовый DML часто может дать огромный выигрыш в производительности, и если существует большая задержка в сети, разница может быть существенной, если Oracle извлекает одну строку за раз.Уменьшение времени выполнения не исправит ошибку, но должно помочь избежать ее.(Хотя Oracle уже может выполнять эту оптимизацию за кулисами.)

РЕДАКТИРОВАТЬ

Массовая обработка может помочь, но лучшим решением, вероятно, будет использование только операторов SQL.,Я провел некоторое тестирование, и приведенная ниже версия работала примерно в 20 раз быстрее, чем оригинал.(Хотя трудно понять, насколько точно мои примерные данные и ссылка на базу данных с самоссылкой моделируют ваши реальные данные.)

BEGIN
    INSERT INTO LOCAL_MASTERTABLE    
      (COL_A, COL_B, COL_C)    
    SELECT COL_A, COL_B, COL_C    
     FROM REMOTE_MASTERTABLE@MY_LINK
     WHERE UPDATED IS NULL;    

    INSERT INTO LOCAL_DETAILSTABLE (COL_A, COL_D, COL_E)
      SELECT REMOTE_DETAILSTABLE.COL_A, REMOTE_DETAILSTABLE.COL_D, REMOTE_DETAILSTABLE.COL_E
      FROM REMOTE_DETAILSTABLE@MY_LINK
        INNER JOIN (SELECT COL_A FROM REMOTE_MASTERTABLE@MY_LINK WHERE UPDATED IS NULL) TRANS
        ON REMOTE_DETAILSTABLE.COL_A = TRANS.COL_A;

    UPDATE REMOTE_MASTERTABLE@MY_LINK SET UPDATED = 1 WHERE UPDATED IS NULL;
END;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...