OOP no VB: classe para controlar transações no ADO
Sempre que o programador chama o método BeginTrans do objeto Connection precisa lembrar-se de chamar o método CommitTrans ou Rollbacktrans para concluir a transação. Se ocorrer um esquecimento, a transação ficará em aberto e as atualizações feitas não serão gravadas no banco de dados nem canceladas. Para ocorrer um erro e o programador decidir sair do procedimento, terá que lembrar-se de chamar Rollbacktrans para todas as transações aninhadas dentro do procedimento. Para automatizar esta tarefa e livrar-nos de ter que lembrar caso a caso de chamar os Rollbacktrans na quantidade necessária, podemos criar uma classe que faz isto por nós.
Abaixo vai o código fonte para você adicionar a um módulo de classe nomeado CTransADO e um exemplo de como usá-lo para controlar transações no ADO. Você não precisará chamar Rollbacktrans quando sair por motivos anormais do procedimento, mas precisará chamar explicitamente CommitTrans para cada transação que precisar enviar suas operações para o banco de dados. A idéia é ter um contador de chamadas a BeginTrans dentro da classe. Este contador é incrementado em 1 a cada chamada a BeginTrans e decrementado a cada chamada a CommitTrans ou Rollbacktrans. O princípio usado aqui é o mesmo já usado nas classes CHourGlass e CLockWindowUpdate, ou seja, ao ser destruído, todo objeto dispara o evento Terminate. Na classe de controle de transações, chamamos o seu método Rollbacktrans para aplicar rollback a todas as transações que estejam pendentes. Com isto garantimos que, ao sair do procedimento e o objeto de controle de transações ser destruído, nenhuma transação para a qual não se tenha aplicado um explícito CommitTrans ou RollBackTrans ficará em aberto.
Para criar a classe, adicione um módulo de classe ao seu projeto, nomeie a classe como CTransADO e insira o código abaixo ao módulo.
Option Explicit
Public oConnection As ADODB.Connection
Public InTrans As Long
Public Sub BegTrans()
If oConnection Is Nothing Then
MsgBox "Faltando informar transação", ,
App.Title
Err.Raise vbObjectError
End If
oConnection.BeginTrans
InTrans = InTrans + 1
End Sub
Public Sub ComTrans()
If oConnection Is Nothing Then
MsgBox "Faltando informar transação", ,
App.Title
Err.Raise vbObjectError
End If
oConnection.CommitTrans
InTrans = InTrans - 1
End Sub
Public Sub RollbackTrans(Optional Todas As Boolean = False)
On Error Resume Next
If Todas Then
Do While InTrans > 0
oConnection.RollbackTrans
InTrans = InTrans - 1
Loop
Else
oConnection.RollbackTrans
InTrans = InTrans - 1
End If
End Sub
Private Sub Class_Initialize()
InTrans = 0
End Sub
Private Sub Class_Terminate()
'caso hajam
transações pendentes, elimina-as
RollbackTrans True
End Sub
Exemplo de uso:
Private Sub ExecutaAcoes(cn as
ADODB.Connection)
Dim
adoTrans As CTransADO
Set adoTrans = New CTransADO
Set adoTrans.oConnection = cn
adoTrans.BegTrans
' faz algumas coisas com o banco de dados aqui
' aninha uma transação
adoTrans.BegTrans
' faz mais algumas operações com o banco de dados aqui
' se ocorrer um erro ou o programador decidir sair do procedimento
' nada precisa ser feito, pois, ao ser destruído na saída do escopo,
' o objeto adoTrans disparará o evento Terminate que aplicará
' um Rollback a todas as transações aninhadas que não tenham
' sido salvas com um CommitTrans explícito.
adoTrans.ComTrans
adoTrans.ComTrans
End Sub