Visual Basic 6 : DAO - Replicando sua base de dados
"Você trabalha como vendedor para uma grande empresa e está acabando de fechar uma negócio com um cliente . Após verificar a disponibilidade do produto em seu notebook você preenche o pedido faz uma conexão com o seu servidor e envia os dados da transação. Vale lembrar que neste momento o mesmo pode estar acontecendo com os 50 vendedores da sua Empresa que estão em campo.(Você esta a 800 Km de distância da sede da companhia e , por falar nisto , já faz uns três meses que você não coloca os pés no escritório.)..."
O pequeno exercício de ficção acima já faz parte integrante do nosso dia a dia. Uma das tecnologias que torna o fato possível é a replicação das informações contidas banco de dados central da companhia. Replicação das informações ? Afinal o que é replicação ?
Replicação de Banco de dados
Podemos definir como replicação o processo de criação de cópias de um banco de dados e a sincronização das mudanças ocorridas nos dados entre todas as cópias. Explicando melhor:
O banco de dados original é definido como Mestre de Construção ( Master Design )
Cada cópia do banco de dados é referenciada como sendo uma Réplica.
O conjunto de todas as réplicas e do Mestre de construção forma o conjunto de replicação
O processo de criar componentes no conjunto de replicação e de manter os dados sincronizados entre as réplicas e o Mestre de construção é chamado replicação do banco de dados
A lógica de replicação vai além de um simples backup do banco de dados , como se poderia supor a primeira vista, pois ao invés de duplicar todos os componentes do banco de dados é realizada a sincronização no conjunto de replicação ( os bancos de dados ) comparando-os registro a registro para assegurar que conterão os mesmos dados e então copiando as alterações do banco de dados Principal(mestre de construção) para qualquer um dos bancos de dados da réplica.
No caso do vendedor , ele carrega no seu notebook uma réplica do banco de dados . Quando faz a conexão com o servidor o processo de sincronização entra em cena e os registros são comparados em sua réplica com os registros do Mestre de Construção ( o banco de dados principal ) . Se você adicionou ou fez qualquer alteração nos registros eles serão copiados e as alterações refletidas no banco de dados Principal. Da mesma forma se qualquer dado novo ou alteração foi feita no banco de dados principal (lembre-se que temos 50 vendedores que podem atualizar a base de dados usando o mesmo processo) elas serão copiadas para sua réplica no mesmo momento.
A replicação pode também ser utilizada para otimizar até um simples Backup do Banco de dados. Assim, em um rede com diversos usuários fazer um backup do banco de dados implica em não disponibilizar o acesso do banco de dados aos usuários durante o processo do backup por razões de integridade e segurança . Neste período de tempo a rede ficara inativa . A réplica resolve o problema pois irá permitir a cópia apenas dos registros alterados desde o último backup e com isso você não precisa copiar o banco de dados inteiro.
Para ambientes onde a atualização das informações precisam ser quase que instantâneas (sistema de seguranças) e onde o processo de atualização dos dados é intenso a replicação do banco de dados não é aconselhável.
Da Teoria a Prática - Fazendo um banco de dados Replicável
A primeira coisa a fazer para utilizar a replicação com um banco de dados é tornar o banco de dados que você deseja replicar em um Mestre de Construção ( Master Design). Vale dizer aqui que vamos utilizar o DAO - Data Access Object - para controlar a réplica. Com isto em mente vamos dar abaixo os objetos DAO que contém propriedades e métodos utilizados no processo de replicação:
Propriedade/Método | Objeto | Descrição |
KeepLocal | TableDef e QueryDef | Determina se o objeto pode se tornar uma réplica |
Replicable | Database, TableDef e QueryDef | Determina se o objeto é duplicado durante a sincronização. |
MakeReplica | Database | Cria uma a partir do Meste de Construção |
Synchronize | Database | Sincroniza um banco de dados de réplica com o Mestre de Construção |
ReplicaFilter | TableDef | Permite fornecer uma cláusula WHERE SQL que rege quais registros da tabela serão duplicados |
PartialReplica | Relation | Em uma réplica parcial permite determinar qual a relação rege a réplica dos registros. |
ReplicableBool | DataBase | Equivalente a propriedade Replicable (Mais difícil definir ) |
Neste artigo vamos utilizar o banco de dados Mestre.mdb no diretório c:\teste . Então antes de tornar nosso banco de dados Replicável vamos dar uma olhada e analisar a sua estrutura:
Usando o aplicativo Visual Data Manager ( Visdata ) no menu Add-Ins do seu Visual Basic , abra o banco de dados Mestre.mdb ( mestre.zip ) - Opção Open Database | Microsoft Access . Fig 1.0
A seguir selecione a opção Utility|Preferences|Include System tables para exibir todas as tabelas do sistema - Fig 2.0
Fig 1.0 - As tabelas do banco de dados | Fig 2.0 - Todas as tabelas do sistema |
Selecione a tabela Clientes e clique na propriedade Fields. Observe os campos da tabela Clientes. Fig 3.0
Para encerrar abra a opção Properties na janela Database Window. Observe as propriedades do banco de dados Mestre.mdb
Fig 3.0 - Os campos da tabela Clientes | Fig 4.0 - As propriedades do banco de dados |
Criando um Mestre de Construção ( Master Design)
A primeira coisa a fazer para usar a réplica com o código DAO é fazer com que o banco de dados possa ser duplicado. Fazemos isto incluindo a propriedade dinâmica - Replicable - ao objeto Database .
Isto deve ser feito nas seguintes etapas:
Fazer uma cópia do banco de dados
Abrir o banco de dados no modo exclusivo
Anexar a propriedade á coleção Properties do objeto
Definir o valor da propriedade Replicable como "T"
Vamos agora criar um mestre de construção do nosso banco de dados Mestre.mdb.
Inicie um novo projeto no VB - STANDARD EXE
Faça uma referência a Microsoft DAO 3.51 library no menu Project|References
No formulário padrão insira uma caixa de texto (name=txtcaminho) e um botão de comando (name=cmdreplicar)
A seguir insira o seguinte código no evento click do botão de comando:
Private Sub cmdreplicar_Click() Dim dbMestre As Database Dim Propriedade As Property Const CaminhoCopia = "c:\teste\copia\CopiaMestre.mdb" On Error GoTo trata_erro 'faz uma copia do banco de dados ( prevenir é bom né...) FileCopy txtcaminho.Text, CaminhoCopia ' abre o banco de dados no modo exclusivo Set dbMestre = OpenDatabase(txtcaminho.Text, True) 'cria e define a propriedade replicable With dbMestre Set Propriedade = .CreateProperty("Replicable", dbText, "T") .Properties.Append Propriedade .Properties("Replicable") = "T" End With MsgBox " O banco de dados foi copiado para " & dbMestre.Name & _ " e sua propriedade Replicable foi definida para : " & dbMestre.Properties("Replicable").Value & _ " => Acabamos de criar um mestre de construção ", vbInformation, " Replicação " dbMestre.Close Exit Sub trata_erro: Select Case Err.Number Case 3367 ' a propriedade replicabel já existe Exit Sub Case Else MsgBox " Erro : " & Err.Description End Select End Sub |
Veja bem você não criou um novo arquivo , apenas modificou o arquivo existente - Mestre.mdb . Esta operação somente pode ser realizada uma única vez. (veja o tratamento de erros onde prevemos tal situação...)
Quais as modificações ocorreram durante o processo ? Vamos mostrar isto a seguir...
1-) A alteração nos campos de cada tabela :
Abra o arquivo Mestre.mdb usando o Visdata e Expanda as propriedades para a tabela clientes. A seguir exiba as propriedades do objeto Fields e observe.Note que foram criados três novos campos para a tabela :
|
|
Figura 5.0 - Os novos campos inseridos durante o processo |
Na verdade os três novos campos são inseridos em todas as tabelas do banco de dados. O que significam ?
s_Generation - identifica os registros que foram alterados. Todos os registros iniciam com o número 1 neste campo . Quando o registro é modificado seu conteúdo muda para 0. Quando a sincronização entre os membros do conjunto de replicação ocorre somente os registros que possuem o valor 0 neste campo são transferidos.
s_GUID - Identifica um registro de forma única. Permanece o mesmo para cada registro através de todos os membros da replica.
s_Lineage - Contém o nome do último membro do conjunto de replicação que atualizou o registro.
2-)Alteração nas tabelas do sistema:
Vamos analisar as tabelas do sistema . Observe a figura abaixa com as novas tabelas inseridas após termos feito o banco de dados replicável:
Deu para perceber que muitas novas tabelas foram inseridas ( compare com figura 2.0). O propósito destas tabelas é gerenciar a sincronização de forma a garantir que durante a replicação todos os membros do conjunto de replicação foram atualizados. Por exemplo: A tabela MSysReplicas contém informação sobre cada membro do conjunto de replicação.
|
|
Figura 6.0 - As novas tabelas do sistema |
2-)Alteração nas propriedades do banco de dados :
Vamos observar as novas propriedades do banco de dados comparando a figura abaixo com a figura 4.0 acima:
Perceba
que novas propriedades foram inseridas.
Observe que agora existe a propriedade Replicable com o valor igual a T. Isto indica que a replica pode ser feita para este banco de dados. Observe que a propriedade ReplicaID foi incluída . Ela identifica o banco de dados de forma única. Então cada replica recebe um valor diferente para ReplicaID. A propriedade DesignMaster também foi criada e indica o Mestre de construção da replica. A nova propriedade LastUptade armazena o código de identificação do último membro de replicação a atualizar o banco de dados. |
|
Figura 7.0 - AS novas propriedades do banco de dados |
Além destas propriedades , cada tabela ganhou nova propriedades. Se você visualizar as propriedades de cada tabela usando Visdata irá perceber isso. Note a propriedade Replicable que tem a mesma função no banco de dados.
É claro que com tantas inclusões o tamanho do banco de dados irá aumentar. Aproximadamente 28 bytes são incluídos para cada registro . Parece pouco mas se considerar todas as tabelas e todos os registros em cada tabela pode ser um aumento considerável. Assim 5 a
Um campo autonumeração é um campo incrementado automaticamente pelo sistema de banco de dados , no caso o Jet. Se você pretende replicar o seu banco de dados, é necessário levar em consideração o tamanho de campo apropriado para o campo AutoNumeração utilizado como chave primária da tabela.
Quando o banco de dados torna-se replicável os campos autonumeração transformam-se em números aleatórios. Quer ver ? abra uma tabela com um campo autonumeração e insira um novo registro , observe o número aleatório atribuído ao campo autonumeração...
Criando Réplicas
Toda cópia de um Mestre de Construção é definida como uma réplica. Vamos então criar uma réplica do nosso banco de dados Master.mdb que já esta pronto para ser replicado.
Para criar uma réplica de um banco de dados replicável usamos o método MakeReplica. Sua sintaxe é:
Sintaxe:
database.MakeReplica replica, description, options
Parâmetro | Descrição |
database | Uma variável objeto que representa um um banco de dados existente. |
replica | Uma STRING que indica o caminho e o nome atribuído a replica criada. |
description | Uma String que descreve a replica que estamos criando.. |
options | Opcional. Uma constante ou combinação de constantes que especifica as características da replica . (* veja abaixo as opções) |
Constante | Descrição |
dbRepMakePartial | Cria uma replica parcial |
dbRepMakeReadOnly | Evita a modificação dos objetos replicáveis da nova replica pelo usuário. As alterações somente ocorrerão durante a sincronização com os membros do conjunto de replicação. |
Private Sub cmdreplica_Click() Dim dbMestre As Database On Error GoTo trata_erro Set dbMestre = OpenDatabase(txtcaminho.Text, True) If dbMestre.Properties("replicable") = "T" Then dbMestre.MakeReplica "c:\teste\Mestre_1.mdb", " Replica de " & txtcaminho.Text dbMestre.Close MsgBox " Foi criada uma copia do banco de dados " & txtcaminho.Text, vbInformation, "Cria Replica" Else MsgBox " Não é possivel criar uma replica para este arquivo ", vbInformation, "Cria Replica" End If Exit Sub trata_erro: MsgBox " Erro : " & Err.Description End Sub |
Com o código acima criamos uma réplica do nosso arquivo Mestre.mdb chamada Mestre_1.mdb no diretório c:\teste.
Voce pode abrir a réplica no Visdata e dar uma olhada nas propriedades do arquivo. O arquivo Mestre_1.mdb pode ser usado para , a partir dele, criarmos novas réplicas.
Sincronizando membros de um conjunto de réplicas
Sincronização é o processo de atualização de dois membros de um conjunto de réplicas pelo intercâmbio de todos os registros e objetos atualizados em cada membro. Dois membros estão sincronizados quando as alterações feitas em um deles tiverem sido aplicadas ao outro.
Obs: conjunto de réplicas é a Estrutura-mestre e todas as réplicas que compartilham a mesma estrutura de banco de dados e identificador de conjunto de réplicas exclusivo.
Para realizar a sincronização dos dados entre os membros de um conjunto de réplicas utilizamos o método Synchronize cuja sintaxe é a seguinte:
database.Synchronize pathname, exchange
Onde:
Argumento | Descrição |
database | Uma variável objeto que representa um objeto Database. |
pathname | Uma String que contém o caminho para a replica de destino com a qual o banco de dados será sincronizado. |
exchange | Constante que indica em qual direção a sincronização será realizada.(Opcional) |
Constante | Descrição |
dbRepExportChanges | Envia as alterações do Banco de dados para o destino.(pathname) |
dbRepImportChanges | Envia as alterações do destino (pathname) para o banco de dados. |
dbRepImpExpChanges | Executa uma troca bidirecional. (É o padrão ) |
dbRepSyncInternet | Realiza uma troca de dados entre arquivos conectados via internet.. |
Antes de fazer a sincronização abra o banco de dados e inclua alguns registros em qualquer tabela. Observe que o campo s_Generation assume o valor zero (0) indicando que o mesmo esta pronto para ser copiado durante a sincronização.
Private Sub cmdsincronizar_Click() Dim dbMestre As Database On Error GoTo trata_erro Set dbMestre = OpenDatabase(txtcaminho.Text, True) dbMestre.Synchronize "c:\teste\Mestre_1.mdb", dbRepImpExpChanges MsgBox " Sincronização realizada com sucesso !", vbInformation, " Sincronização " Exit Sub trata_erro: MsgBox " Erro : " & Err.Description End Sub |
neste código temos a sincronização entre o banco de dados Mestre.mdb e a replica Mestre_1.mdb.
Para realizar a sincronização na Internet podemos usar o código abaixo:
Sub
Sincronizar_Web()
|
Criando uma Réplica Parcial
É claro que haverá ocasiões onde você não desejará transmitir todo o conjunto de dados do seu mestre de construção para a réplica por razões de segurança. ( quando os dados forem sigilosos(senhas), estratégicos (planejamento) ou confidenciais (dados pessoais) )
Quando isto ocorrer você pode configurar a replicação de modo que somente os dados que você deseja sejam trocados durante o processo de sincronização. Chamamos isto de uma réplica parcial pois copia somente os dados que um certo usuário provavelmente usará.
Uma Réplica Parcial é um banco de dados que não duplica todos os dados no Mestre de Construção. Para criar uma réplica parcial siga as estas etapas :
Para exemplificar vamos criar uma replica parcial para o banco de dados Mestre.mdb, onde iremos restringir a cópia dos dados da tabela Clientes aos clientes do estado de São Paulo , ou seja , onde o campo Estado = "SP" .
1-) Primeiro vamos criar a réplica parcial - veja o código abaixo associado ao um novo botão de comando (name=cmd_cria_replica_parcial). Com isso estaremos um arquivo com a estrutura do Mestre de construção sem dados algum. Os dados virão na segunda etapa:
Private Sub cmd_cria_replica_parcial_Click() Dim tabelas As TableDef Dim dbMestre As Database Const CaminhoReplica = "c:\teste\Mestre_Parcial.mdb" On Error GoTo trata_erro Set dbMestre = OpenDatabase(txtcaminho.Text, True) dbMestre.MakeReplica CaminhoReplica, "Partial", dbRepMakePartial MsgBox " Foi criada uma réplica parcial com sucesso !", vbInformation, " Sincronização " dbMestre.Close Exit Sub trata_erro: MsgBox " Erro : " & Err.Description End Sub |
2-) Executando a réplica parcial e recebendo os dados - Após a replica parcial ter sido criada podemos usar o código abaixo associado a um novo botão de comando ( name = cmd_executa_replica_parcial):
Private Sub cmd_executa_replica_parcial_Click() Dim tabela As TableDef Dim dbMestre As Database Const CaminhoCopia = "c:\teste\copia\CopiaMestre.mdb" On Error GoTo trata_erro Set dbMestre = OpenDatabase(CaminhoCopia, True) Set tabela = dbMestre.TableDefs("Clientes") 'aplica o filtro na tabela tabela.ReplicaFilter = "ESTADO = 'SP'" 'preenche com os dados do Mestre de Construcao dbMestre.PopulatePartial txtcaminho.Text Exit Sub trata_erro: MsgBox " Erro : " & Err.Description End Sub |
Os conflitos podem ocorrer em diversas situações , uma delas seria quando o mesmo registro foi alterado em diferentes replicas entre as sincronizações . Isto poderia atribuir valores distintos para o mesmo registro o que levaria a usuários distintos visualizarem valores distintos para o mesmo registro. Isto também ocorre quando dois usuários atualizam o mesmo registro em dois bancos de dados diferentes em um conjunto de replicas. A sincronização de dois bancos de dados seria bem-sucedida mas apenas um dos dois conjuntos de alterações seria aplicado a ambos os bancos de dados.
Um conflito de chave única pode ocorrer em uma das formas a seguir:
Um conflito de validação em nível de tabela ocorre quando são inseridos dados que violam uma regra de validação em nível de tabela que restringe os valores ou tipos de dados que podem ser inseridos em uma tabela.
Um conflito de atualização de integridade referencial ocorre quando a chave primária é atualizada em uma réplica e novos registros filho fazem referência ao valor original da chave primária são adicionados a uma réplica diferente.
Um conflito de exclusão de integridade referencial ocorre quando um registro de chave primária é excluído em uma réplica enquanto novos registros filho que fazem referência à chave primária excluída são adicionados em uma segunda réplica.
Um bloqueio de conflito ocorre quando o registro não pode ser aplicado durante a sincronização porque outro usuário bloqueou a tabela.
Um conflito de violação de chave externa ocorre quando há um registro de chave primária inválido. Isso pode ser causado por qualquer um dos outros tipos de conflitos.
A lógica que o Jet Engine usa para resolver os conflitos é a seguinte:
O membro do conjunto de replicação que altera o registro o maior número de vezes vence o conflito
Se este número for igual para todos os membros do conjunto de replicação o Jet seleciona o registro da tabela com o menor valor para ReplicaID
Palavra final
Ao implementar a replicação de um banco de dados você deverá fazer mais de uma cópia do banco de dados original - o Mestre de Construção. Então como e quando atualizar os membros do conjunto de replicação ? Você deve ser criterioso e adotar uma estratégia para fazer isto.
A topologia mais utilizada ,e talvez a mais simples, para implementar a replicação é a topologia Estrela. Nela temos um banco de dados central ( O mestre de construção ) com o qual todos os membros do conjunto de réplicas realizarão a sincronização. Assim nenhuma replicação será realizada entre os membros do conjunto das réplicas. ( A topologia tem um pequeno problema: quando o banco de dados central estiver fora do ar , ninguém consegue fazer a replicação...)
A topologia Linear também pode ser usada para sincronização das réplicas. Nela a replica A sincroniza com a replica B que sincroniza com a replica C e vice-versa. ( A topologia de Anel é idêntica a Linear..)
Até um próximo artigo...
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET