Replicação de Dados com InterBase/Firebird



Documentos relacionados
Replicação de Dados no Interbase

BANCO DE DADOS II Prof. Ricardo Rodrigues Barcelar

Sistemas de Informação

DESENVOLVIMENTO DE SOFTWARE

Triggers em PostgreSQL. Linguagem de Programação de Banco de Dados. Triggers em PostgreSQL. Triggers em PostgreSQL

APOSTILA BANCO DE DADOS INTRODUÇÃO A LINGUAGEM SQL

Banco de Dados. Um momento crucial na organização dos dados é a forma com que cadastramos estes dados, a estrutura de armazenamento que criamos.

CADERNOS DE INFORMÁTICA Nº 1. Fundamentos de Informática I - Word Sumário

COMANDO DA AERONÁUTICA ESCOLA DE ESPECIALISTAS DE AERONÁUTICA SUBDIVISÃO DE ADMISSÃO E DE SELEÇÃO

PL/pgSQL por Diversão e Lucro

Autor: Tiago Lone Nível: Básico Criação: 19/12/2005 Última versão: 18/12/2006. PdP. Pesquisa e Desenvolvimento de Produtos

A linguagem SQL

ADMINISTRAÇÃO DE BANCOS DE DADOS MÓDULO 13

SISTEMA BRENA DE AUTOMAÇÃO COMERCIAL

Listando itens em ComboBox e gravando os dados no Banco de Dados MySQL.

Tabelas vista de estrutura

Tarefa Orientada 18 Procedimentos armazenados

Modelo Cliente/Servidor Por HIARLY ALVES

LINGUAGEM SQL. DML - Linguagem de Manipulação de Dados

BD Oracle. Licenciatura em Engenharia Informática e Computação. Bases de Dados 2003/04

ITIL v3 - Operação de Serviço - Parte 1

Laboratório de Banco de Dados II Aula 1. Stored Procedures

Bases de Dados 2007/2008. Aula 8

Neste artigo, serão apresentados os principais conceitos sobre os TRIGGERS e sua aplicabilidade.

Logado no OracleXE vamos acessar a opção:

Informática básica Telecentro/Infocentro Acessa-SP

Comandos de repetição while

SQL Linguagem de Definição de Dados. Banco de Dados Profa. Dra. Cristina Dutra de Aguiar Ciferri

Sistemas Operacionais. Curso Técnico Integrado Profa: Michelle Nery

Linguagem de Consulta - SQL

AULA 2 INTERAÇÃO COM O BANCO DE DADOS

Data Transformation Services (DTS) por Anderson Ferreira Souza

Trabalhando com conexão ao banco de dados MySQL no Lazarus. Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011

Integração de livros fiscais com o Microsoft Dynamics AX 2009

Aula 4 Estatística Conceitos básicos

LINGUAGEM SQL PARA CONSULTAS EM MICROSOFT ACCESS

Banco de Dados. Profª. Ana Leda

Modem e rede local. Guia do usuário

Laboratório de Banco de Dados Prof. Luiz Vivacqua. PL/pgSQL A Linguagem de programação do PostgreSQL

Gatilhos (Triggers) Prof. Márcio Bueno Elaborado por Maria Lígia B. Perkusich

Tarefa Orientada 19 Triggers

RELATÓRIOS GERENCIAIS

Segurança. Guia do Usuário

MANUAL DA SECRETARIA

Primeiros passos das Planilhas de Obra v2.6

Banco de Dados Avançados Banco de Dados Ativo

Indústria de Cartões de Pagamento (PCI) Padrão de segurança de dados. Resumo de Alterações da Versão 2.0 para a 3.0 do PCI-DSS

Técnicas de Normalização por Phaser

Introdução a Banco de Dados Aula 03. Prof. Silvestri

Gerenciamento da Integração (PMBoK 5ª ed.)

Usando PostgreSQL na Regra de Negócio de um ERP. Fabiano Machado Dias Eduardo Wolak

Regras Métodos Identificadores Variáveis Constantes Tipos de dados Comandos de atribuição Operadores aritméticos, relacionais e lógicos

1. Explicando Roteamento um exemplo prático. Através da análise de uns exemplos simples será possível compreender como o roteamento funciona.

Criando um banco de dados

A SEGUIR ALGUMAS DICAS PARA O DESENVOLVIMENTO DE UM PROJETO CIENTÍFICO

Sistemas Operacionais. Prof. André Y. Kusumoto

Conceitos Básicos de Rede. Um manual para empresas com até 75 computadores

Oracle PL/SQL Overview

Conectar diferentes pesquisas na internet por um menu

Resolução de Problemas de Rede. Disciplina: Suporte Remoto Prof. Etelvira Leite

Engenharia de Software II

Apostilas OBJETIVA Atendente Comercial / Carteiro / Op. Triagem e Transbordo CORREIOS - Concurso Público º CADERNO. Índice

Usando o Conference Manager do Microsoft Outlook

Metadados. 1. Introdução. 2. O que são Metadados? 3. O Valor dos Metadados

Transações Seguras em Bancos de Dados (MySQL)

Resumo de alterações da versão 2.0 para a 3.0 do PA-DSS

Banco de Dados II. Triggers e Functions. Prof. Moser Fagundes. Curso TSI Instituto Federal Sul-Rio-Grandense (IFSul) Campus Charqueadas

Guia de utilização da notação BPMN

Capítulo 2. VARIÁVEIS DO TIPO INTEIRO

Generated by Foxit PDF Creator Foxit Software For evaluation only. Capitulo 1

Um jogo de preencher casas

Prof.: Clayton Maciel Costa

Manual das planilhas de Obras v2.5

Prova de Fundamentos de Bancos de Dados 2 a Prova

Bases de Dados 2007/2008. Aula 9

Busca em Memória. Secundária

Neste tópico, abordaremos a funcionalidade de segurança fornecida com o SAP Business One.

Cópia de Segurança e Recuperação Manual do utilizador

Representação de Algoritmos - Linguagens de Programação

Introdução ao SQL. Aécio Costa

CONFIGURAÇÃO DO BIOS E CARACTERÍSTICAS DE SEGURANÇA

GESTÃO DE INFORMAÇÃO PESSOAL OUTLOOK (1)

Projeto da Disciplina Parte1: Estudo de Viabilidade. Um Estudo de Viabilidade

Programação SQL. Introdução

ETEC DR. EMÍLIO HENRNANDEZ AGUILAR PROGRAMAÇÃO DE COMPUTADORES II PROFESSOR RAFAEL BARRETO

LINX POSTOS AUTOSYSTEM

SQL: Definição de tabelas, Modificações à Base de Dados

Figura 1: tela inicial do BlueControl COMO COLOCAR A SALA DE INFORMÁTICA EM FUNCIONAMENTO?

PROCEDIMENTOS ARMAZENADOS (Stored Procedures)

Este artigo abaixo foi produzido originalmente para a Network Core Wiki. Reproduzo-a aqui na íntegra. Publicado originalmente em 07/12/2007.


3.1 Definições Uma classe é a descrição de um tipo de objeto.

Manipulação de Arquivos em Pascal

Mais configuração OptraImage

Alteração do POC (Decreto de Lei nº. 35/2005) no sispoc

SIMULADO DO TESTE DE RESOLUÇÃO DE PROBLEMAS

Projeto de Banco de Dados

Transcrição:

Replicação de Dados com InterBase/Firebird By Matt Hopkins, Dunstan Thomas (UK) Ltd. Borland Developers Conference 1998 Este artigo irá descrever os conceitos básicos da replicação de dados e como isto pode ser implementado de maneira relativamente simples usando as características embutidas no InterBase/Firebird. O que é Replicação de Dados? Replicação de dados é copia de dados para uma ou mais Bases de Dados de forma que a informação seja consiste em todas as bases. Existem dois tipos básicos de replicação síncrona e assíncrona. Com replicação síncrona, todas as cópias ou réplicas dos dados são mantidas exatamente sincronizadas e consistentes. Se uma cópia é atualizada as mudanças serão imediatamente aplicadas para todas as outras bases de dados com a mesma transação. A replicação síncrona é apropriada quando esta exata consistência é importante para o negócio. Com replicação assíncrona, ou armazene e replique, as cópias dos dados ficarão temporariamente desincronizadas. Se uma cópia é atualizada, a mudança será aplicada e propagada para as outras cópias num segundo passo, em uma transação separada que pode ocorrer segundos, horas ou dias mais tarde. As cópias por outro lado podem ficar temporariamente sem sincronia, mas a uma certa altura os dados irão convergir para um mesmo valor em todas as cópias. Este artigo descreverá exclusivamente a replicação assíncrona de dados. Quais Componentes são necessários para a Replicação de Dados? Capturando as mudanças da Origem dos Dados Todas as estratégias de replicação de dados requerem um método para capturar as mudanças em uma base de dados replicada. Estão aqui dois mecanismos: Log de Transações e Triggers (Gatilhos). O log de transação se parece com um mecanismo chamado log sniffing que copia as transações marcadas para replicação para uma área de preparação para transmissão. Esta técnica é argumentada por ter baixo impacto no servidor da base dados por que ela requer um mínimo de utilização da CPU quando esta lendo o log em memória e escrevendo para o disco. Isto é implementado em produtos de replicação por fornecedores como Informix, Sybase, e MS SQL/Server. O segundo mecanismo é usar triggers da base de dados para propagar as mudanças quando elas ocorrem em uma tabela de log da base de dados para transmissão. Como a linguagem procedural da base de dados pode ser usada para estes métodos, ela provê maior flexibilidade em decidir quais os dados serão replicados. Esta técnica de replicação é implementada por fornecedores como Ingress e Oracle. Esta será também a técnica que nós utilizaremos quando replicarmos com InterBase/Firebird. Transmitir Mudanças da Base de Dados Origem para todas as Bases de Dados Alvo Transmitir mudanças para replicação requer softwares que leiam os logs (registros) de mudanças e se conectem a todos os servidores de bases de dados alvo localizados em uma LAN ou WAN e aplique estas mudanças na base de dados alvo. Este software é conhecido como gerenciador de replicação e devem também gerar log s de erros e conflitos de atualização. Como estes Componentes de Replicação de Dados podem ser Implementados em InterBase/Firebird? Logando as Mudanças dos Dados Certo, para criarmos o nosso ENGINE de replicação nós primeiro precisamos criar duas Bases de Dados de exemplo (origem e destino) com duas tabela idênticas em cada um.

CREATE DATABE "source.gdb" PAGE_SIZE 1024 CREATE TABLE TEAMS ( TEAM_ID INTEGER NOT NULL, TEAM_NAME VARCHAR(100), TEAM_MGR VARCHAR(40), PRIMARY KEY (TEAM_ID)); CREATE TABLE CHANGES ( CHANGE_ID INTEGER NOT NULL, CHANGE_TYPE CHAR(1) NOT NULL, SOURCE_KEY_FIELD VARCHAR(31) NOT NULL, SOURCE_KEY INTEGER NOT NULL, SOURCE_TABLE VARCHAR(31), USERNAME VARCHAR(31), PRIMARY KEY (CHANGE_ID)); CREATE GENERATOR NEW_TEAM_ID; CREATE GENERATOR NEW_CHANGE_ID; Agora vamos adicionar a trigger para a tabela CHANGES para pegar o valor único do generator do InterBase/Firebird. CREATE TRIGGER CHANGES_NEWID FOR CHANGES BEFORE INSERT NEW.CHANGE_ID = GEN_ID(NEW_CHANGE_ID,1); END Repare que nós não estamos adicionando uma trigger para gerar um único ID para a tabela TEAMS; a razão para isto será discutida na próxima seção. Agora que temos nossas bases de dados de exemplos, nós precisamos criar um mecanismo para logar todas as mudanças nas nossas tabelas. Como mencionado anteriormente, nós incorporaremos um método trigger para logar as mudanças das nossas tabelas para replicação. Esta técnica nos traz o benefício de ser fácil de usar, ao contrário dos log s de transação, permitem o uso de uma lógica de programação personalizada através da linguagem procedural do InterBase/Firebird. Como são três os tipos de mudanças que podem ocorrer em uma tabela Inserção, Atualização e Deleção, nós precisaremos três triggers para cada tabela que será replicada: /* After an Insert */ CREATE TRIGGER TEAMS_REPL_INSERT FOR TEAMS AFTER INSERT INSERT INTO CHANGES (CHANGE_TYPE, SOURCE_KEY_FIELD, SOURCE_KEY, SOURCE_TABLE,USERNAME) VALUES ("I","TEAM_ID",NEW.TEAM_ID,"TEAMS",USER);

/* After an Update */ CREATE TRIGGER TEAMS_REPL_UPDATE FOR TEAMS AFTER UPDATE INSERT INTO CHANGES (CHANGE_TYPE, SOURCE_KEY_FIELD, SOURCE_KEY, SOURCE_TABLE,USERNAME) VALUES ("U","TEAM_ID",NEW.TEAM_ID,"TEAMS",USER); /* After a Delete */ CREATE TRIGGER TEAMS_REPL_DELETE FOR TEAMS AFTER DELETE INSERT INTO CHANGES (CHANGE_TYPE, SOURCE_KEY_FIELD, SOURCE_KEY, SOURCE_TABLE,USERNAME) VALUES ("D","TEAM_ID",OLD.TEAM_ID,"TEAMS",USER); Isto é tudo o que é necessário para logar mudanças de dados para replicação de dados em InterBase/Firebird. Observe que por causa da simplicidade, nós precisamos que as tabelas replicadas tenham uma chave inteira única e que somente este é o que será armazenado na tabela CHANGES. Nós podemos armazenar todos valores dos campos que foram mudados, mas como nós replicaremos um SNAPSHOT dos dados armazenando apenas as chaves e a operação, nós podemos pegar o valor corrente em cada tabela com o mecanismo de replicação. Uma coisa a mais antes de passarmos para o mecanismo de replicação nós precisaremos criar a base de dados de destino com o mesmo metadata da origem. Isto pode ser feito através da geração da cópia da base de dados origem com o flag metadadata-only marcado e restaurar esta cópia no destino.gdb. Replicando as Mudanças nos Dados Agora nós iremos criar o servidor de replicação utilizando Delphi 32-bit. A idéia é que o usuário possa configurar a replicação para um certo tempo ou acioná-la manualmente pressionando um botão Replicar Agora. Um log de todas as atividades será mostrado em Memo e todos os erros que ocorrerem serão mostrados outro Memo. O alias de origem e o alias alvo serão passados como parâmetros de linha de comando, algo como isto: C:\REPLD SOURCEDB TARGETDB

O fonte para garantir que serão sempre dois parâmetros é este: if (ParamStr(1) = '') or (ParamStr(2) = '') then MessageDlg('Usage: "REPLD.EXE SOURCE_ALI TARGET_ALI"',mtError,[mbOK],0) Else Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; Toda replicação será feita em um procedimento Replicate, como este: procedure TForm1.Replicate; var qrychangelist : TQuery; strchangetype : String; qrychangelist := TQuery.create(Application); with qrychangelist do DatabaseName := 'SourceDB'; sql.add('select * from changes'); open; while not eof do if (fieldbyname('change_type').asstring = 'I') then strchangetype := 'Insert'; ReplicateInsert(fieldByName('SOURCE_TABLE').asString, fieldbyname('source_key_field').asstring, fieldbyname('source_key').asinteger) end else if (fieldbyname('change_type').asstring = 'U') then strchangetype := 'Update'; ReplicateUpdate(fieldByName('SOURCE_TABLE').asString, fieldbyname('source_key_field').asstring, fieldbyname('source_key').asinteger) end else if (fieldbyname('change_type').asstring = 'D') then strchangetype := 'Delete'; ReplicateDelete(fieldByName('SOURCE_TABLE').asString, fieldbyname('source_key_field').asstring, fieldbyname('source_key').asinteger) memolog.lines.add( DateTimeToStr(Now)+' '+strchangetype+ ' '+fieldbyname('source_key').asstring+ ' on '+fieldbyname('source_table').asstring); DeleteFromChanges(fieldByName('CHANGE_ID').asInteger); next;

close; qrychangelist.free; E para cada ação (Inserir, Deletar, Atualizar) um procedimento individual é chamado desta forma: Replicar Inserções: procedure TForm1.ReplicateInsert(const strtablename, strkeyfield: String; const ikey: Integer); var qrysource, qrytarget : TQuery; i : SmallInt; qrysource := TQuery.create(Application); with qrysource do DatabaseName := 'SourceDB'; with sql do add('select * from '+strtablename); add(' where ('+strkeyfield+' = '+IntToStr(iKey)+');'); open; while not eof do qrytarget := TQuery.create(Application); with qrytarget do DatabaseName := 'TargetDB'; with sql do add('insert into '+strtablename); add('('); for i := 0 to qrysource.fieldcount-1 do if (i < qrysource.fieldcount-1) then add(' '+qrysource.fields[i].fieldname+',') else add(' '+qrysource.fields[i].fieldname) add(')'); add('values'); add('('); for i := 0 to qrysource.fieldcount-1 do

if (i < qrysource.fieldcount-1) then add(' :'+qrysource.fields[i].fieldname+',') else add(' :'+qrysource.fields[i].fieldname) add(')'); prepare; for i := 0 to qrysource.fieldcount-1 do qrytarget.params[i].asstring := qrysource.fields[i].asstring; execsql; qrytarget.free; next; close; except on e: Exception do memoerrors.lines.add(datetimetostr(now)+' '+e.message); qrysource.free; Replicar Atualizações: procedure TForm1.ReplicateUpdate( const strtablename, strkeyfield: String; const ikey: Integer); var qrysource, qrytarget : TQuery; i : SmallInt; qrysource := TQuery.create(Application); with qrysource do DatabaseName := 'SourceDB'; with sql do add('select * from '+strtablename); add(' where ('+strkeyfield+' = '+IntToStr(iKey)+');'); open; while not eof do

qrytarget := TQuery.create(Application); with qrytarget do DatabaseName := 'TargetDB'; with sql do add('update '+strtablename); add('set'); for i := 0 to qrysource.fieldcount-1 do if (i < qrysource.fieldcount-1) then add(' '+qrysource.fields[i].fieldname+ ' = :'+qrysource.fields[i].fieldname+',') else add(' '+qrysource.fields[i].fieldname+ ' = :'+qrysource.fields[i].fieldname) add(' where ('+strkeyfield+' = '+IntToStr(iKey)+');'); prepare; for i := 0 to qrysource.fieldcount-1 do qrytarget.params[i].asstring := qrysource.fields[i].asstring; execsql; qrytarget.free; next; close; except on e: Exception do memoerrors.lines.add(datetimetostr(now)+' '+e.message); qrysource.free;

Replicando Deleções: procedure TForm1.ReplicateDelete(const strtablename, strkeyfield: String; const ikey: Integer); var qrysource : TQuery; i : SmallInt; qrysource := TQuery.create(Application); with qrysource do DatabaseName := 'TargetDB'; sql.add('delete from '+strtablename); sql.add(' where ('+strkeyfield+' = '+IntToStr(iKey)+')'); execsql; execsql; except on e: Exception do memoerrors.lines.add(datetimetostr(now)+' '+e.message); qrysource.free; Note que este exemplo não suporta tipos BLOB. É necessário um pouco mais de código para implementar esta funcionalidade, mas é possível utilizá-los. Agora, conecte o value do SpinBox com o timer e então você ajusta o ciclo de replicação: procedure TForm1.SpinEdit1Change(Sender: TObject); Timer1.Interval := (SpinEdit1.Value * 1000); Execute isto, e enquanto REPLD está rodando, faça algumas mudanças na tabela TEAMS na base de dados de origem certificando-se de adicionar um valor de chave única e então cheque a base de dados alvo (depois do ciclo de replicação) para ver as mudanças replicadas. Replicação Bi-direcional Enquanto estiver na base de dados alvo, cheque as mudanças da tabela. Você pode observar que as mudanças replicadas da base de dados de origem também aparecem nesta tabela. O problema é que o mecanismo para logar nossas mudanças não diferencia entre aquelas mudanças feitas pelo usuário e as mudanças feitas pelo mecanismo de replicação. Se nós iniciarmos uma replicação bi-direcional usando nosso REPLD sem especificar um usuário de replicação nós podemos criar um loop infinito. Portanto, nós necessitaremos criar um usuário de replicação para este exemplo nós o chamaremos de REPLICATE em cada servidor InterBase/Firebird que estiver rodando e recusar as mudanças feitas por este usuário. Isto faz que tenhamos que mudar as trigger s de log de mudanças para cada tabela que necessite replicação como segue:

/* After an Insert */ ALTER TRIGGER TEAMS_REPL_INSERT FOR TEAMS AFTER INSERT IF (USER <> "REPLICATE") THEN INSERT INTO CHANGES (CHANGE_TYPE, SOURCE_KEY_FIELD, SOURCE_KEY, SOURCE_TABLE,USERNAME) VALUES ("I","TEAM_ID",NEW.TEAM_ID,"TEAMS",USER); /* After an Update */ ALTER TRIGGER TEAMS_REPL_UPDATE FOR TEAMS AFTER UPDATE IF (USER <> "REPLICATE") THEN INSERT INTO CHANGES (CHANGE_TYPE, SOURCE_KEY_FIELD, SOURCE_KEY, SOURCE_TABLE,USERNAME) VALUES ("U","TEAM_ID",NEW.TEAM_ID,"TEAMS",USER); /* After a Delete */ ALTER TRIGGER TEAMS_REPL_DELETE FOR TEAMS AFTER DELETE IF (USER <> "REPLICATE") THEN INSERT INTO CHANGES (CHANGE_TYPE, SOURCE_KEY_FIELD, SOURCE_KEY, SOURCE_TABLE,USERNAME) VALUES ("D","TEAM_ID",OLD.TEAM_ID,"TEAMS",USER); Agora nós rodaremos duas versões do REPLD: C:\REPLD SOURCEDB TARGETDB C:\REPLD TARGETDB SOURCEDB E quando nós formos logar nestes bancos, nós precisaremos logar como REPLICATE. Isto nos proverá uma replicação bi-direcional. Você pode notar que quando você move de um modelo de replicação mestre-escravo para um modelo ponto-a-ponto muitas complexidades ao redor devem ser consideradas antes de implementar a replicação. Estas dicas, e como fazer uso de algumas delas são descritas na próxima seção.

Replicando as Mudanças Quando Ocorrem (próximo à replicação síncrona) Se nós precisarmos replicar as tabelas quando elas são alteradas e não em um determinado ciclo de tempo, nós termos que utilizar os mecanismos de eventos do InterBase/Firebird. Isto requer dois passos gerar (ou postar) um evento e responder a este evento. Para gerar o evento, nós precisaremos adicionar uma nova trigger na tabela CHANGES: CREATE TRIGGER CHANGES_ALERT FOR TEAMS AFTER INSERT POST_EVENT "NEW_CHANGE"; Para responder ao evento, nós precisaremos adicionar um componente IBEventAlerter a nossa aplicação REPLD, registrando o interesse no evento NEW_CHANGE pela adição disto na propriedade Events, e ligando o evento OnEventAlert ao procedimento replicate: procedure TForm1.IBEventAlerter1EventAlert(Sender: TObject; EventName: string; EventCount: Longint; var CancelAlerts: Boolean); Replicate; Tente isto. Replicando Tabelas com Chaves Compostas Para simplificarmos, no exemplo seguinte nós iremos replicar somente tabelas com índice simples (inteiros). A mesma técnica, com pequenas alterações, pode ser usada para manusear tabelas com índices compostos. A principal diferença entre manusear chaves compostas mistas e chaves inteiras simples é a forma como as mudanças são logadas. Ao invés de uma simples tabela CHANGES, no caso de chaves compostas é necessário uma tabela de "log" para cada tabela base que será replicada. Replicar através uma WAN com R (Remote Access Services) O serviço de Acesso Remoto (R) em Windows NT e Rede Discada (Dial-Up) em Windows 95 permitem que muitos serviços possam estar disponíveis em uma rede que pode ser acessada através de um modem. Isto quer dizer que se quisermos podemos modificar o mecanismo de replicação para replicarmos bases remotas através de um modem, adicionando suporte à R. O caminho mais fácil em Delphi para implementar R é através de um componente. Existe uma enorme quantidade de componentes shareware e freeware para isto na Internet. Para estes exemplo, nós usaremos TRas do Daniel Polistchuck que está disponível em http://www.delphi32.com. Como o componente e a API R descomplicou as coisas para nós, adicionar R ao REPLD precisará somente algumas poucas linhas de código. Primeiro nós precisamos modificar o procedimento Replicate e então este chamará a conexão R quando as mudanças forem replicadas.

procedure TForm1.Replicate; with qrychangelist do DatabaseName := 'SourceDB'; sql.add('select * from changes'); if active then close; open; if (recordcount > 0) then memolog.lines.add(datetimetostr(now)+' Dialing DT'); R1.EnName := 'DT'; R1.Connect; Como você pode ver, nós adicionamos um teste para verificar se existem registros e chamamos o componente R para chamar a conexão DT. Nós também teremos que mover o resto do código que existia anteriormente para o evento OnConnect do componente R e tornar a query (qrychangelist) global para o form: procedure TForm1.R1Connect(Sender: TObject); var strchangetype : String; with qrychangelist do memolog.lines.add(datetimetostr(now)+' Connected to DT'); while not eof do if (fieldbyname('change_type').asstring = 'I') then strchangetype := 'Insert'; ReplicateInsert( fieldbyname('source_table').asstring, fieldbyname('source_key_field').asstring, fieldbyname('source_key').asinteger) end else if (fieldbyname('change_type').asstring = 'U') then strchangetype := 'Update'; ReplicateUpdate( fieldbyname('source_table').asstring, fieldbyname('source_key_field').asstring, fieldbyname('source_key').asinteger) end else if (fieldbyname('change_type').asstring = 'D') then strchangetype := 'Delete'; ReplicateDelete( fieldbyname('source_table').asstring, fieldbyname('source_key_field').asstring, fieldbyname('source_key').asinteger)

memolog.lines.add( DateTimeToStr(Now)+' '+strchangetype+' '+ fieldbyname('source_key').asstring+ ' on '+fieldbyname('source_table').asstring); DeleteFromChanges(fieldByName('CHANGE_ID').asInteger); next; close; R1.Disconnect; memolog.lines.add(datetimetostr(now)+' Disconnected from DT'); Isto é tudo que nós precisamos para conectar a uma base remota, replicando qualquer mudança, e então desconectando. Isto é simples? Não. Com a replicação vem um amontoado de problemas que necessitam ser prevenidos através de boas decisões, planejamento adequado e algumas vezes uma boa programação no software. Seguem algumas dicas: Conflitos de Atualização Assegurar a convergência em ambientes de replicação assíncrona é crítico para toda aplicação. De qualquer forma, o que acontece se o mesmo dado (Ex.: a mesma coluna na mesma linha) é atualizado em duas bases ao mesmo tempo, ou o mais precisamente dentro do mesmo intervalo de replicação? Isto é conhecido como um conflito de atualização. Para assegurar a convergência, conflitos de atualização devem ser detectados e resolvidos para que então o dado tenha o mesmo valor em cada base. Quanto mais freqüente você propagar as suas mudanças (isto é, menos intervalo de replicação ou período de tempo), menos conflitos de atualização ocorrerão. Alternativamente, conflitos de atualização podem ser evitados pela limitação de posse ou o direito de atualização dado à um elemento para uma base. De fato, muitos acreditam que a resolução de conflitos é um processo que preferencialmente cabe ao desenvolvedor de software. Pela eliminação de possibilidades de conflitos através de planejamento e procedimento, o software não precisará resolver conflitos, que em teoria nunca ocorrerão. Esta visão, por outro lado, é um tanto quanto limitada quando clientes precisam que várias opções para resolução de conflitos sejam construídas na ferramenta de replicação. Chaves Únicas e Generators Tipicamente quando trabalhamos com chaves inteiras únicas, uma trigger before insert (antes da inserção) é adicionada com chamadas a geradores de números para adicionar novos valores. Quando trabalhamos com replicação isto pode gerar problemas. O problema é manter a sincronização entre duas ou mais bases de dados. Dê uma olhada no seguinte exemplo: Na primeira base, o gerador usado para uma certa tabela é 5. Quando um novo registro é adicionado, um trigger incrementa to valor do gerador em 1 e fornece 6 para a chave do novo registro. O registro é replicado para uma outra base de dados identica. Na base dois, o valor do gerador é 100. Quando o registro da primeira base é inserido na tabela correspondente, o trigger sobrepõe o 6 com o novo valor incrementado, valor 101. A solução tem duas partes. A primeira é confiar no cliente para dar valores ás chaves e não usar triggers. Segundo, reservar blocos de números para as várias base e então cada uma será dona de certos valores de chave. Um integer em Interbase/Firebird pode armazenar até 2 bilhões de números, então, cada bloco pode ser dividido em um conjunto de milhões, se necessário.

Os geradores de cada base podem ser inicializados com o número inicial de cada bloco usando-se os comando SET GENERATOR: SET GENERATOR GEN_NAME TO 1000000; Inicialização Se você replicar a fonte de dados nos alvos, então você deve inicialiazar aqueles alvos de maneira que iniciem em sincronia com a fonte. Tipicamente, você pode fazer isto com uma cópia completa dos dados para a base alvo; simplesmente implementando um dump da base origem e recarregando isto na base alvo. Mudanças na DDL O que acontece quando você muda o metadata? Se você adicionar um campo a uma tabela em uma base, estas mudanças também precisarão ser feitas em todas as bases replicadas. Sumário Replicação de bases de dados é um tópico interessante e está sendo requisitado (ou preferencialmente exigido) por mais e mais clientes em todo o mundo, de fato, mais de 50% dos projetos iniciados em dezembro de 1996 na Dunstan Thomas tem replicação como um requerimento de sistema. A replicação tem o potencial de prover maior rendimento, tempo de resposta rápido e reduzir custo de comunicação e gargalos nas redes para usuários-finais geograficamente dispersos. Com InterBase/Firebird e o poder do Microsoft R, replicação de dados não é somente possível, mas está disponível hoje. Artigo Original: http://www.ibphoenix.com/main.nfs?a=ibphoenixapp&page=ibp_howto10 Matt Hopkins Tradução e adaptação: Comunidade Firebird de Língua Portuguesa Visite a Comunidade em: Jiancarlos Kleinebing polo@softline.com.br http://www.comunidade-firebird.org A Comunidade Firebird de Língua Portuguesa foi autorizada pelo Autor do Original para elaborar esta tradução.