TRANSACOES ENTRE VARIOS COMPONENTES MTS/COM .
Transações entre vários componentes MTS/COM+.
Primeiramente muito obrigado para quem se interessar em responder a este tópico porque ele ficou gigantesco, mas esclarecedor.
Criei UM componente de Dados para que seus métodos forneça os principais comandos SQL personalizados (Select, Insert retornando Affected Rows ou não, Update e Delete através de procedures ou diretamente na string de comando, etc)
Esta classe de dados está configurada no projeto e no MTS apenas para dar suporte a transações, já que nem sempre se faz necessário como no caso dos Selects ou Update e Insert e Delete de registros únicos ...
O processo:
A- Tenho o componente cCliente.dll com os métodos InserirCliente (Público) e InsereTelefone (Private).
B- O método InserirCliente recebe o array Telefone() como um de seus parà ¢metros.
C- Insiro os dados do cliente na respectiva tabela urilizando nosso componete de dados instanciado.
D- Destruo o Objeto de dados com Set=Nothing por que não será mais necessário nesta função.
E- Percorro o array Telefone() e para cada linha chamo a função InserirTelefone() que por sua vez instancia uma nova versão do nosso objDados que efetiva a inclusão.
F- Para testar o processo travo a tabela telefone de forma a forçar um erro e verificar a recuperação ...
G- A mensagem de erro retornada entre os componentes é perfeita
H- A transação não é respeitada, ou seja, o cliente fica lá cadastrado e os telefones não.
Ambiente:
O Server MTS utilizado é o mesmo computador do VB (WXP-Pro/SP2)
Componente cCliente.dll suporta transações (Não requer)
Código:
Somente se alguém se manifestar, o texto já está bem longo !!!
Escrevi uma bÃblia, eu sei, mas para alguém que esteja tentando aprender o pra quê do MTS e as formas de se ter um ambiente de aplicação distribuida acho que será um excelente tópico.
Primeiramente muito obrigado para quem se interessar em responder a este tópico porque ele ficou gigantesco, mas esclarecedor.
Criei UM componente de Dados para que seus métodos forneça os principais comandos SQL personalizados (Select, Insert retornando Affected Rows ou não, Update e Delete através de procedures ou diretamente na string de comando, etc)
Esta classe de dados está configurada no projeto e no MTS apenas para dar suporte a transações, já que nem sempre se faz necessário como no caso dos Selects ou Update e Insert e Delete de registros únicos ...
O processo:
A- Tenho o componente cCliente.dll com os métodos InserirCliente (Público) e InsereTelefone (Private).
B- O método InserirCliente recebe o array Telefone() como um de seus parà ¢metros.
C- Insiro os dados do cliente na respectiva tabela urilizando nosso componete de dados instanciado.
D- Destruo o Objeto de dados com Set=Nothing por que não será mais necessário nesta função.
E- Percorro o array Telefone() e para cada linha chamo a função InserirTelefone() que por sua vez instancia uma nova versão do nosso objDados que efetiva a inclusão.
F- Para testar o processo travo a tabela telefone de forma a forçar um erro e verificar a recuperação ...
G- A mensagem de erro retornada entre os componentes é perfeita
H- A transação não é respeitada, ou seja, o cliente fica lá cadastrado e os telefones não.
Ambiente:
O Server MTS utilizado é o mesmo computador do VB (WXP-Pro/SP2)
Componente cCliente.dll suporta transações (Não requer)
Código:
Somente se alguém se manifestar, o texto já está bem longo !!!
Escrevi uma bÃblia, eu sei, mas para alguém que esteja tentando aprender o pra quê do MTS e as formas de se ter um ambiente de aplicação distribuida acho que será um excelente tópico.
Olá, preciso muito mesmo resolver esta questão.
Se alguém tiver um projeto exemplo de componente que chama outro de dados tratando possÃveis erros ou só uma pequena luz no final do túnel me ajude, plz !!!
Se alguém tiver um projeto exemplo de componente que chama outro de dados tratando possÃveis erros ou só uma pequena luz no final do túnel me ajude, plz !!!
'Método InsereCliente da classe cliente Resumido
'Esta Dll está configurada para "Requerer Nova transação"
'Esta Dll está configurada para "Requerer Nova transação"
Public Sub InsereCliente( ByVal N-PARAMETERS, byVal Telefones())
Dim a As Integer
Dim x As Integer
Dim objDADOS As cDados.clsDados
Dim objCTXT As ObjectContext
On Error GoTo trataErro
'Iniciamos a preparação da string de comando SQL "simplificada"
'para enviar ao componente de dados
strSQL = "INSERT INTO cliente("
strSQL = strSQL & " id_cliente"
strSQL = strSQL & ")VALUES("
strSQL = strSQL & lngID_CLIENTE & ")"
'Marca o contexto da transação deste objeto
Set objCTXT = GetObjectContext()
'Inicia uma nova transação da minha classe de manipulação
'de dados que deve ser filha da atual.
Set objDADOS = objCTXT.CreateInstance("cDados.clsDados")
'O código abaixo deveria estar em uma transação controlada pelo MTS
'Tal qual Connection.BegginTrans, mas consultando o BD após a execução
'o registro ja consta sem nenhum tipo de "trava" a espera de
'uma confirmação.
'Inserimos na tabela cliente utilizando o método insert do nosso
'componente de manipulação genérica de dados que fica disponÃvel para
'todas aplicações que utilizarem a mesma base.
objDADOS.Insert (strSQL)
Set objDADOS = Nothing
'Laço de inclusão de telefones aonde forçamos o erro para teste travando
'a tabela.
For x=0 To Ubound(Telefones())
'Nada diferente de preparar uma string SQL, instanciar um novo
'cDados.clsDados e Inserir na Telefone
'Esta função é private e encontra-se neste mesmo componente.
InsereTelefone(lngID_CLIENTE, Telefone(x))
Next
'Tudo ocorreu perfeitamente, MTS confirme todas operações.
objCTXT.SetComplete
Set objCTXT= Nothing
On Error Return 0
Exit Sub
trataErro:
'Algo falhou, MTS cancele todas operações.
objCTXT.SetAbort
Set objCTXT= Nothing
Set objDADOS = Nothing
Exit Sub
'Método Insert da classe cDados Resumido
'Esta Dll está configurada para "Requerer transação"
'Esta Dll está configurada para "Requerer transação"
Public Sub Insert(ByVal STR_SQL As String)
Dim strSQL As String
Dim CNN As ADODB.Connection
10 On Error GoTo ErrorHandler
20 strSQL = STR_SQL
30 Set CNN = New ADODB.Connection
40 CNN.CursorLocation = adUseClient
'Obviamente ReadDSN é uma função que nos retorna uma ConectionString
50 CNN.Open ReadDSN
60 CNN.Execute strSQL, , adExecuteNoRecords
70 CNN.Close
80 Set CNN = Nothing
'O componete usa transação, avisemos ao MTS que o método obteve exito ...
90 GetObjectContext.SetComplete
100 Exit Sub
ErrorHandler:
110 If Not CNN Is Nothing Then
120 Set CNN = Nothing
130 End If
' ... ou não
140 GetObjectContext.SetAbort
150 App.LogEvent "cDados.clsDados.Insert" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
160 Err.Raise Err.Number, Err.Source, Err.Description
End Sub
Maravilha !!!
Embora o código acima não seja o mais perfeito do mundo e de lógica incontestável, o mecanismo de utilização do MTS funciona perfeitamente, ou seja, se a função InsereTelefone() falhar todas operações com o BD serão aboratadas ... contanto que vc utilize um Banco de Dados que suporte Transações pelo MTS, o que NÃO é o caso do Acces XP (e nenhum outro).
Migrei parte da base para MSSQL Server 2000, funcionou belezura ... então ficae um exemplo de código que definitivamente funkou entre um componente generico de dados e sua utilização por um outro sob controle do MTS ... espero que ajude alguem algum dia (avise se quiser emerson_tadeu@ig.com.br)
Embora o código acima não seja o mais perfeito do mundo e de lógica incontestável, o mecanismo de utilização do MTS funciona perfeitamente, ou seja, se a função InsereTelefone() falhar todas operações com o BD serão aboratadas ... contanto que vc utilize um Banco de Dados que suporte Transações pelo MTS, o que NÃO é o caso do Acces XP (e nenhum outro).
Migrei parte da base para MSSQL Server 2000, funcionou belezura ... então ficae um exemplo de código que definitivamente funkou entre um componente generico de dados e sua utilização por um outro sob controle do MTS ... espero que ajude alguem algum dia (avise se quiser emerson_tadeu@ig.com.br)
Como faço para dar pontos amim mesmo ??
Hehehe, embora pareça um mala desta vez realmente axo que mereço pois forqam 5 dias de pesquisa ininterruptas.
Hehehe, embora pareça um mala desta vez realmente axo que mereço pois forqam 5 dias de pesquisa ininterruptas.
Tópico encerrado , respostas não são mais permitidas