Sincronismo de banco de dados em Hot Standby


#1

Olá,

Estou desenvolvendo uma aplicação em Hot Standby com um Database adicional no SQL Server além do Database de eventos do E3.

Este Database está sendo preenchido pela aplicação desenvolvida com sucesso nos 2 servidores quando ambos estão conectados à rede, porém quando desconectamos um da rede, fazemos uma alteração no banco e conectamos novamente, os dados novos não estão sendo sincronizados para o outro servidor.

Os bancos estão com suas propriedades “EnableSynchronization” iguais a true.

Encontrei um outro tópico resolvido no Fórum que é semelhante (Dúvidas: Replicação de dados em aplicações Hot-StandBy), porém não compreendi exatamente o que deve ser feito para resolver.

Segue trecho do script da tela em que estou inserindo os dados no banco:

'**************************************************************************************************************************
'*** Conexão SQLSERVER. Criando as variáveis ADO. Estabelecendo a conexão.
Set conn = CreateObject (“ADODB.Connection”)
Set rs = CreateObject (“ADODB.Recordset”)
conn.Open "Provider = SQLOLEDB ; Data Source = " & Application.GetObject(“Comum.DBActiveServer”).Value & "\SQLSCL ; Trusted_Connection = Sim ; Initial Catalog = SCLHigMackCFG ; User ID = sclhig ; Password = sclhig "

’ -------------------------------------------------------------------------------------------------------------------------
'*** Conexão SQLSERVER Standby. Criando as variáveis ADO. Estabelecendo a conexão.
Set conn2 = CreateObject (“ADODB.Connection”)
Set rs2 = CreateObject (“ADODB.Recordset”)
conn2.Open "Provider = SQLOLEDB ; Data Source = " & Application.GetObject(“Comum.DBStandbyServer”).Value & "\SQLSCL ; Trusted_Connection = Sim ; Initial Catalog = SCLHigMackCFG ; User ID = sclhig ; Password = sclhig "
’ -------------------------------------------------------------------------------------------------------------------------

'*** escreve a query - I N S E R E D A D O S
if Screen.Item(“OptionCad”).Value = true then

if msgbox("Deseja Realmente Cadastrar a Rotina ?", vbYesNo + vbExclamation, "Atenção")=6 then

	'*** executa a query
	Query2 = "insert into Rotinas (RotID,RotHab,RotNome,PH1_Inicio,PH1_Fim,PH1_SemanaInicio,PH1_SemanaFim,Espec_Inicio,Espec_Fim,RotDesc,RotUser,RotDt,RotDevicesInicio,RotDevicesFim) Values ('" & Screen.Item("IDRot").Value & "','" & check & "','" & Screen.Item("NomeRot").Value & "','" & InicRot & "','" & FimRot & "','" & SemanaInicio & "','" & SemanaFim & "','" & EspIni & "','" & EspFim & "','" & Screen.Item("DescRot").Value & "','" & Screen.Item("Usuario").Value & "','" & DtRot & "','" & EquiptoInicio & "','" & EquiptoFim & "')"
	conn.Execute Query2
	Screen.Item("E3Browser1").Requery()
	'*** Fecha a conexão com o banco de dados
	conn.Close
	set conn = nothing

	' executa a Query no servidor Standby ------------------------------------------------------------------------------
	Query2a = "insert into Rotinas (RotID,RotHab,RotNome,PH1_Inicio,PH1_Fim,PH1_SemanaInicio,PH1_SemanaFim,Espec_Inicio,Espec_Fim,RotDesc,RotUser,RotDt,RotDevicesInicio,RotDevicesFim) Values ('" & Screen.Item("IDRot").Value & "','" & check & "','" & Screen.Item("NomeRot").Value & "','" & InicRot & "','" & FimRot & "','" & SemanaInicio & "','" & SemanaFim & "','" & EspIni & "','" & EspFim & "','" & Screen.Item("DescRot").Value & "','" & Screen.Item("Usuario").Value & "','" & DtRot & "','" & EquiptoInicio & "','" & EquiptoFim & "')"
	conn2.Execute Query2a
	'*** Fecha a conexão com o banco de dados
	conn2.Close
	set conn2 = nothing
	' -----------------------------------------------------------------------------------------------------------------

	'Servidor de Alarmes
	Set Op = Application.GetObject("ServidorAlarmes")
	'Registra Cmd
	Call Op. LogTrackingEvent("Rotina Agendada: " & Screen.Item("IDRot").Value & " - " & Screen.Item("NomeRot").Value & " cadastrada.", Screen.Item("Usuario").Value,"SAO",3, , , , , , ,"")

	msgbox "Rotina: " & Screen.Item("IDRot").Value & " - " & Screen.Item("NomeRot").Value & " - " & Screen.Item("DescRot").Value & Chr(13) & Chr(13) & "Cadastrada com sucesso."

	Screen.Item("IDRot").Value = Screen.Item("IDRot").Value + 1	

end if

end if

Segue imagem da configuração do DBServer:

Favor auxiliar em descobrir o que está faltando para funcionar e se possível detalhar melhor a solução indicada do outro tópico citado.

Desde já agradeço.


(Paulo Gustavo Süffert) #2

Fernando,

Os dados só serão sincronizados se passarem pelas filas de operações do banco (arquivos E3I e E3O). Isso não acontece quando se utiliza uma conexão ADO por script como no seu caso.

Você tem que usar um objeto Histórico ou um objeto Consulta. Veja exemplo no link abaixo.


(Régis Andrei Kensy) #3

Fernando, bom dia!

Já passei anteriormente por essa mesma dificuldade em um projeto anterior, porém com a ajuda do pessoal do forum eu consegui resolver, por isso fico muito feliz em poder ajudar.

Verifiquei que o @pgustavo já esclareceu anteriormente a dúvida, mas gostaria de complementar a resposta de uma forma mais detalhada e didática:

Quando você envia comandos para o banco por meio do objeto ADODB.Connection, tais comandos não são replicados pelo E3. O objeto “ADODB.Connection” faz parte de uma biblioteca compartilhada do próprio Windows, por isso o E3 não tem controle sobre o fluxo de conexões e comandos que passa por esse objeto.
Toda vez que você cria uma conexão por meio do objeto “ADODB.Connection”, todo e qualquer comando é enviado diretamente ao banco de dados, ou é perdido (em casos onde o banco de dados está fora de alcance).

Se ao invés de você instanciar o objeto “ADODB.Connection”, você instanciar no seu script o objeto de consulta do próprio E3, nesse caso o cenário muda totalmente. Todos comandos passam pelos arquivos E3I e E3O, que nada mais são do que uma fila de comandos a serem executados posteriormente.
Quando o banco de dados está ao alcance do E3, esses comandos são processados quase que instantaneamente e de forma cíclica, na ordem em que foram enfileirados. Porém quando o servidor está fora de alcance e a conexão falha, esses comandos vão se mantendo nessa fila, até que a conexão com o banco seja reestabelecida.
De uma forma básica esse é o conceito utilizado pelo E3 para garantir a replicação dos dados.

É claro que para tudo isso funcionar, além de utilizar os objetos de conexão e consulta do próprio E3, você precisa observar os seguintes detalhes:

  1. A propriedade EnableSynchronization do objeto de banco de dados deve estar habilitada;
  2. O método Execute do objeto consulta possui um parâmetro chamado ExecuteImmediate, esse parâmetro precisa estar em False.

Quando você configura o parâmetro ExecuteImmediate para True, você está “dizendo” ao componente que o comando deve ser enviado “diretamente” para o banco, sem passar pela “fila de execução”, ou seja, em caso de desconexão do banco, comandos executados por esse objeto não serão replicados.

Espero ter ajudado.


#4

Muito obrigado @pgustavo e @RegisKensy! As instruções foram muito valiosas e resolveram o problema.