Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.06.17;
Скачать: CL | DM;

Вниз

Можно ли в оракле в контексте одной сессии переключать 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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.022 c
2-1180290744
Bogdan1024
2007-05-27 22:32
2007.06.17
case () of для энумированных величин


2-1179816234
unnamed777
2007-05-22 10:43
2007.06.17
GetFileSize


15-1179597858
Rawed
2007-05-19 22:04
2007.06.17
Часы в Windows постоянно сбиваются!!


2-1173950118
Mishenka
2007-03-15 12:15
2007.06.17
Работа с MySql


2-1180174977
GeLLeR
2007-05-26 14:22
2007.06.17
Вопрос про dll.