OOP no VB:classe para controlar transações no ADO

Visual Basic, VB .NET, ASP, Active X, Access, SQL Server

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