-- Tablas maestras de replicacion drop table repsecuencia; create table repsecuencia( nombre varchar2(10) not null, valor number(10) not null, constraint repsecuencia_pk primary key (nombre) ); --se debe crear una tabla por instancia, ejem: instancia def, tabla repcomdef, instancia inv, tabla repcominv create table repcomdef( secuencia number(10) not null, servidor varchar2(30) not null, rutina varchar2(64) not null, texto varchar2(4000) not null, constraint repcomandos_pk primary key(secuencia) ); create table reperrores( secuencia number(10) not null, servidor varchar2(30) not null, rutina varchar2(64) not null, texto varchar2(4000) not null, mensaje varchar2(400) not null, constraint reperrores_pk primary key(secuencia) ); create table repinstancias( tabla varchar2(30) not null, servidor varchar2(30) not null, instancia varchar2(5) default 'DEF' not null constraint repinstancias_instancia_ck check (instancia not in ('REP','ERR')), estado varchar2(1) not null, constraint repinstancias_estado_ck check (estado in ('A', 'C', 'I')), constraint repsinstancias_pk primary key(tabla, servidor) ); create table repinstanciasdef( tabla varchar2(30) not null, servidor varchar2(30) not null, estadoini varchar2(1) not null, estadofin varchar2(1) not null, constraint repsinstanciasdef_pk primary key(tabla, servidor) ); create or replace view repinstanciasv as select 'xx' origen, 'xx' tabla, 'xx' servidor, 'xx' Instancia from dual; --Se debe Definir cual es el servidor master de replicación INSERT INTO GENPREFSCLA(MODULO, OBJETO, CLAVE, DESCRIPCION) VALUES('SGE', 'INICIO', 'SERVMASTERREP', 'Nombre del Servidor Master de Replicacion'); INSERT INTO GENPREFSVAL(CIA, MODULO, OBJETO, CLAVE, INSTANCIA, VALOR) VALUES('001', 'SGE', 'INICIO', 'SERVMASTERREP', 'INICIO', 'VISMAR'); -- Las dos secuencias deben ser iniciadas insert into repsecuencia values ('REP',0); insert into repsecuencia values ('ERR',0); Commit; ------------------------------------------------------------------------------------------------------ --***************************crear solo en server master*******************--------------- create table reptablas( tabla varchar2(30) not null, paquete varchar2(30) not null, constraint reptablas_pk primary key(tabla) ); Create Table RepPlantilla( tabla varchar2(30) not null, columna varchar2(30) not null, tipo char(1) not null constraint RepTemplate_Tipo_Ck Check (tipo in ('P', 'U', 'R', 'S', 'A', 'I')), personalizado char(1) not null constraint RepTemplate_Personalizado_Ck Check (Personalizado in ('S', 'N')), constraint RepTemplate_Pk primary key (Tabla, Columna) ); create table repservidor( servidor varchar2(30) not null, descripcion varchar2(30) not null, constraint RepServidor_Pk primary key(servidor) ); alter table repplantilla add constraint RepTablas_Plantilla_Fk foreign key (Tabla) references RepTablas (Tabla); alter table repinstancias add constraint RepTablas_Instancias_Fk foreign key (Tabla) references RepTablas (Tabla); alter table repinstancias add constraint RepServidor_Instancias_Fk foreign key (Servidor) references RepServidor (Servidor); create snapshot log on RepServidor; create snapshot log on RepTablas; create snapshot log on RepPlantilla; --***************************crear solo en server master hasta aca*******************--------------- ------------------------------------------------------------------------------------------------------ --***************************crear solo en servers clientes*******************--------------- define nombrets='DATOS' define dblink='@vismar' create snapshot RepServidor tablespace &nombrets storage (initial 10K next 10K) refresh fast as select * from RepServidor&dblink; create snapshot RepTablas tablespace &nombrets storage (initial 10K next 10K) refresh fast as select * from RepTablas&dblink; create snapshot RepPlantilla tablespace &nombrets storage (initial 10K next 10K) refresh fast as select * from RepPlantilla&dblink; --***************************crear solo en servers clientes*******************--------------- ------------------------------------------------------------------------------------------------------ @genarcreplic @replicacionins --crear un job por cada instancia set serveroutput on Declare jobno binary_integer; BEGIN DBMS_JOB.SUBMIT(jobno, 'repsync.Replicar(''DEF'', 20);', SYSDATE, null); DBMS_OUTPUT.PUT_LINE(jobno); COMMIT; END; / --------**************************Hasta Aqui llega lo importante*************************--- -- Tablas de prueba para probar el concepto create table xxx( x1 varchar2(30) not null, y1 number(14,2) not null, z1 date not null, control varchar2(3) default 'LOC' not null, constraint xxx_pk primary key(x1) ); create table yyy( x1 varchar2(30) not null, y1 number(14,2) not null, z1 date not null, control varchar2(3) default 'LOC' not null, constraint yyy_pk primary key(x1) ); -- Cada tabla a replicar debe estar registrada aca insert into repservidores values ('xxx','vismar','repinv','DEF'); insert into repservidores values ('xxx','visany','repinv','DEF'); -- Ahora procedemos a poner a prueba el ejemplo insert into xxx values ('A',1,sysdate,'LOC'); insert into xxx values ('B',2,sysdate,'LOC'); insert into xxx values ('C',3,sysdate,'LOC'); insert into xxx values ('D'||chr(10),3,sysdate,'LOC'); insert into xxx values ('E'||chr(9),3,sysdate,'LOC'); insert into xxx values ('F'||chr(13),3,sysdate,'LOC'); insert into xxx values ('G'||chr(13)||chr(10),3,sysdate,'LOC'); insert into xxx values ('I'''||chr(10),3,sysdate,'LOC'); update xxx set y1=y1+5.5 where x1 in ('A','B'); -- Fin de Pruebas -- Viendo comandos en cola select secuencia, servidor, substr(texto,1,30) from repcomandos order by secuencia; -- Viendo excepciones select secuencia, substr(mensaje,1,200) from reperrores where secuencia in (0) order by secuencia; -- Comparando tablas replicadas select * from xxx; select x1, y1, to_char(z1,'dd hh24:mi:ss') from yyy; -- Viendo el estado de los servidores select servidor||' '||replicacion.lapsoservidor(servidor) servidor from (select distinct servidor from repservidor); -- Deteniendo un JOB si tiene suerte y sabe el numero (SYS JOB$) BEGIN --DBMS_JOB.REMOVE(4); COMMIT; END; / begin replicacion.FijarEstado('vismar', 'SinServ'); end; / create or replace package repinv is procedure insxxx(pX1 in varchar2, pz1 in date, pY1 in number); procedure actxxx(pX1old in varchar2, pX1 in varchar2, pz1 in date, pY1 in number); procedure delxxx(pX1 in varchar2); end; / create or replace package body repinv is procedure insxxx(pX1 in varchar2, pZ1 in date, pY1 in number) is begin insert into yyy (x1, z1, y1, control) values (pX1, pZ1, pY1, 'REP'); end; procedure actxxx(pX1old in varchar2, pX1 in varchar2, pZ1 in date, pY1 in number) is begin update yyy set x1=pX1, y1=y1+pY1, z1=pz1, control='REP' where x1=pX1old; if sql%notfound then insert into yyy (x1, z1, y1, control) values (pX1, pZ1, pY1, 'REP'); end if; end; procedure delxxx(pX1 in varchar2) is begin delete from yyy where x1=pX1; end; end; / CREATE OR REPLACE TRIGGER REPLICA_XXX AFTER INSERT OR UPDATE OR DELETE ON XXX FOR EACH ROW BEGIN If Inserting and :new.control='LOC' Then --Opcion ...insertarCom('Servidor', 'def', repinv.act','xxx'...); Replicacion.EjecutarCom('repinv.act','xxx',xrp.val(:new.x1)||xrp.val(:new.z1)||xrp.val(:new.y1)); elsif Updating and :new.control='LOC' then Replicacion.EjecutarCom('repinv.act','xxx',xrp.val(:new.x1)||xrp.val(:new.z1)||xrp.val(:new.y1-:old.y1)); elsif Deleting then Replicacion.EjecutarCom('repinv.del','xxx',xrp.val(:old.x1)||xrp.val(:old.z1)||xrp.val(-:old.y1)); end if; END; / -- $paquete.$accion --Para detener los jobs de replicacion begin begin --insert into repsecuencia values ('DEF', 1); exception when dup_val_on_index then update repsecuencia set valor=1 where nombre='STP'; end; commit; end; / BEGIN DBMS_JOB.REMOVE(28); COMMIT; END; / declare vConsec Repcomdef.secuencia%type; begin vconsec := replicacion.replicarsig('DEF'); end; / 0) 1-Key siempre es simple 2-Number siempre es acumulado 1) xxx keys datas 2) xxx keys k1 k2 k3 datas d1 d2 d3 3) ki: nombre 4) di: nombre tipo 5) tipo: acumalado simple 6) simple: :new.di 7) acumulada: :new.di-:old.di reptemplates tabla in_articulo llaves cod_cia, cod_articulo (tipo=K) datos otras columnas simple (tipo=S o A o I) 2) generador (template) ==> trigger, paquete ----------------------------------------------------------- Al dar commit: ERROR en línea 1: ORA-02054: transacción 2.38.14492 dudosa ORA-02068: error grave de CANDY ORA-03113: fin de archivo en el canal de comunicación al hacer select en la tabla: ERROR en línea 1: ORA-12801: error señalizado en el servidor P000 de consultas paralelas ORA-01591: bloqueo mantenido por la transacción dudosa distribuida 2.38.14492 Al ponerse on line el cliente se debe esperar un tiempo prudencial y se podrá seguir trabajando. Ora-01591 Cause: Trying to access resource that is locked by a dead two-phase commit transaction that is in prepared state. Action: DBA should query the pending_trans$ and related tables, and attempt to repair network connection(s) to coordinator and commit point. If timely repair is not possible, DBA should contact DBA at commit point if known or end user for correct outcome, or use heuristic default if given to issue a heuristic commit or abort command to finalize the local portion of the distributed transaction. ORA-01591: Lock held by in-doubt distributed transaction 99.99.99999 A distributed transaction failed and is holding a lock. To see what this transaction was, use following select: select e.sql_text, d.osuser,d.username from v$transaction c, v$session d, v$sqlarea e where d.taddr = c.addr and e.address = d.prev_sql_addr and c.xidusn = <1st Part of Transaction -ID> and c.xidslot =<2nd Part of Transaction -ID> and c.xidsqn = <3rd Part of Transaction -ID>; After that, you can rollback the transaction using the 'rollback force' statement, or use the dbms_transaction.rollback_force('XID') packaged procedure.