Форум: "Базы";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];
ВнизМожно ли в оракле в контексте одной сессии переключать DBLink ? Найти похожие ветки
← →
ANB © (2007-03-23 13:40) [0]Значиться, пишу самопальную псевдорепликацию на триггерах.
С передачей данных из подчиненного сервера в головной проблем нету - тупо по DBLink с одинаковым именем типа DBMaster.
Сейчас дошел до передачи данных из головы в подчиненные сервера.
По спец. таблице я определяю список серверов (и имена DBLink к ним), на которые нужно протолкнуть изменения.
Если в триггерах все засунуть в динамический SQL, то получается жутко нечитаемо, т.к. сами триггера тоже будут генериться динамически (их больно много, а алгоритм в принципе одинаковый).
Делать кучу ифов - тоже хреново, т.к. довольно большие одинаковые блоки будут повторяться для разных дблинков и триггер будет слишком здоровым, плюс их придется перегенерять при добавлении дополнительных серверов.
Вот думаю, как бы подсунуть конструкцию типа
insert into Table1@DBFilial, где DBFilial можно было бы подключать к разным дблинкам.
Можно было делать так :
CREATE OR REPLACE SYNONYM DBFilial FOR DBFilial2
однако это изменение распространиться сразу на все сессии и поломает другие триггера.
Можно ли такую фичу как нибудь поаккуратнее слепить ?
← →
Reindeer Moss Eater © (2007-03-23 14:04) [1]execute immediate?
← →
ANB © (2007-03-23 14:33) [2]
> execute immediate?
Дык писал уже - жутко нечитаемо, но, похоже, выхода другого нету.
← →
Petr V. Abramov © (2007-03-23 16:06) [3]а нафига проталкивать? пусть сами забирают по своим линкам, раз уж класть сами умеют.
← →
ANB © (2007-03-23 17:00) [4]
> Petr V. Abramov © (23.03.07 16:06) [3]
А по какому событию ? Придется как в штатной репликации - по таймеру. А нам нужно немедленно.
← →
Petr V. Abramov © (2007-03-23 21:22) [5]триггер на какой-нить лажовой таблице на стороне филиала, который инициирует процесс синхронизации? dbms_aq?
← →
ANB © (2007-03-26 12:06) [6]
> Petr V. Abramov © (23.03.07 21:22) [5]
это идея. правда, все равно на голове без динамического скл не обойтись, но он тогда одинаковым будет . . .
Оставлю на рефакторинг, уже написал честную толкашку на динамическом скл.
← →
Ломброзо © (2007-03-26 12:46) [7]может, проще в файле HOSTS IP-шники динамически менять? :)
← →
ANB © (2007-03-26 13:06) [8]
> Ломброзо © (26.03.07 12:46) [7]
Из триггера или хранимки ?
ИМХО : Это еще больший изврат, чем вложенный динамический скл :)
← →
ANB © (2007-03-27 11:50) [9]
> триггер на какой-нить лажовой таблице на стороне филиала,
> который инициирует процесс синхронизации? dbms_aq?
И как передавать данные строки ? Если только ID передать, то триггер на голове упадет по мутации при попытке достать запись или придется извращаться с со статемент триггерами.
← →
Кщд © (2007-03-28 10:12) [10]ANB © (23.03.07 13:40)
что если сделать объектный тип, в котором реализовать Вашу "кучу ифов"
на вход передавать соответствущие параметры
и, соответственно, единообразно использвоать его во всех автогенерируемых триггерах
← →
evvcom © (2007-03-28 10:55) [11]> [9] ANB © (27.03.07 11:50)
> то триггер на голове упадет по мутации при попытке достать
> запись
По мутации не упадет. Эти изменения в другой сессии/транзакции видны не будут.
Не совсем понял, что нужно, но кажется, что dbms_aq действительно здесь будет очень красивым решением. Хотя знаком с этим пока только теоретически и думаю, что хлопот по реализации будет даже поболее хлопот по устранению мутаций в статемент триггере. Хотя, может я и ошибаюсь :)
← →
Petr V. abramov (not at home) (2007-03-28 11:10) [12]со стороны голови пишешь что-то типа
insert into t1@flial2 values ("sync starting...")
на стороне филиала на t1 срабатывает триггер, который запускает хранимку, которая начинаетт тянуть с головы по ей (хранимке) известному алгоритму. где тут мутация? по-моему, все дубово, но эффективно
← →
ANB © (2007-03-28 11:16) [13]
> Petr V. abramov (not at home) (28.03.07 11:10) [12]
я пока сгенерил триггера на голове, которые динамическим скл инсертят/апдейтят/удаляют в филиалах в цикле по нужным дблинкам.
Но вашу идею проверю. Не факт, что она будет сильно проще и не факт что будет работать - оракл не любит, когда селекают таблицу, которая в этот момент меняется. Впрочем, я сейчас попробую эту идею на тестовых табличках . . .
← →
Petr V. abramov (not at home) (2007-03-28 11:21) [14]> оракл не любит, когда селекают таблицу
а где такое происходит в [12]?
← →
ANB © (2007-03-28 11:30) [15]
> Petr V. abramov (not at home) (28.03.07 11:21) [14]
Проверил :
-- На филиале :
create table Test_1
(
ID integer,
F1 varchar2(255),
constraint PK_Test_1 primary key (ID)
)
create table Test_Events_1
(
ID integer,
Table_Name varchar2(30),
constraint PK_Test_Events_1 primary key (ID)
)
create or replace procedure Repl_Proc_Test_1 (p_ID integer)
is
begin
insert into Test_1 (ID, F1)
select ID, F1 from Test_1@DBMaster where ID = p_ID;
end;
CREATE OR REPLACE TRIGGER REPL_TRG_Test_Events_1
AFTER DELETE OR INSERT OR UPDATE
ON Test_Events_1
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
tmpVar NUMBER;
BEGIN
if inserting then
Repl_Proc_Test_1(:New.ID);
end if;
END REPL_TRG_Test_1;
-- На голове :
create table Test_1
(
ID integer,
F1 varchar2(255),
constraint PK_Test_1 primary key (ID)
)
CREATE OR REPLACE TRIGGER REPL_TRG_TEST_1
AFTER DELETE OR INSERT OR UPDATE
ON TEST_1
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
tmpVar NUMBER;
BEGIN
if inserting then
insert into Test_Events_1@DBFilial2 (ID, Table_Name) values (:New.ID, "TEST_1");
end if;
END REPL_TRG_Test_1;
Вставка записи прекрасно среплицировалась !
Т.е. идея вполне работоспособна.
Правда, трудоемкость написания не особо уменьшается, но большая часть кода уезжает на филиал, что лучше. Плюс на филиале будет статический скл - намного удобнее при отладке.
Позже, если руки дойдут, зарефакторю эту штуку.
Еще бы в таком случае выяснить вопрос - как динамически создать пакет/хранимку, если ее текст будет больше 32Кб ?
← →
ANB © (2007-03-28 11:31) [16]
> а где такое происходит в [12]?
Самый прикол, что если бы эта хранимка жила на голове, то мутация была бы обеспечена :)
Млин, когда оракл эту "фичу" уберет ?
← →
Petr V. abramov (not at home) (2007-03-28 12:13) [17]> Правда, трудоемкость написания не особо уменьшается,
я так понимаю, на голове остается только цикл с
execute immediate "insert into t1||cr.link_name||" values..."
← →
ANB © (2007-03-28 13:35) [18]
> Petr V. abramov (not at home) (28.03.07 12:13) [17]
Эт на голове. Зато на филиале надо на каждую таблицу либо отдельную хранимку рисовать (или пихать в здоровенный пакет, но я не знаю как с длинным динамическим SQL работать) или на основании словаря генерить DML динамически, что не шустро, а скорость - довольно критическое требование, голову нельзя притормаживать.
Толстый плюс - если рисовать набор хранимок, то они будут на обычном скл, что облегчает отладку и читабельность.
← →
evvcom © (2007-03-28 14:20) [19]> [13] ANB © (28.03.07 11:16)
> оракл не любит, когда селекают таблицу, которая в этот момент
> меняется.
> [16] ANB © (28.03.07 11:31)
> Самый прикол, что если бы эта хранимка жила на голове, то
> мутация была бы обеспечена :)
Не факт. Даже в триггере строки есть вариант селектнуть эту же изменяющуюся таблицу :) Главное, чтобы этот селект не видел изменений. А достигается это просто: вызовом процедуры с прагмой autonomous_transaction. Остается только для себя уяснить, важны ли тебе эти изменения в селекте или нет, тогда и решать, годится такой способ или нет. В твоем случае с филиальным сервером у тебя через dblink организуется дополнительная сессия, из которой естественно изменений в незакоммиченной сессии не видно. Потому ни о каких мутациях речи быть не может.
← →
ANB © (2007-03-28 14:37) [20]
> естественно изменений в незакоммиченной сессии не видно.
Не прав. Если ты смотрел опубликованный мной код, то там видно, что я из сессии на филиале лезу в табличку на голову и достаю незакоммиченную только что добавленную запись.
А при роллбэке все нормально откатывается из обоих таблиц.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.046 c