ADO.NET - Usando Transações


Transações podem ser vistas como um grupo de operações combinadas em uma unidade lógica de trabalho ; são usadas para controlar e manter a consistência e a integridade de cada ação em uma transação a despeito dos erros que poderão ocorrer no sistema. 

Vejamos um exemplo para ilustrar melhor o conceito: 

  1. Você esta fazendo uma transferência da poupança para a conta corrente.
  2. Ao realizar o saque da poupança a transação é iniciada.
  3. A transação é vista como o grupo de operações :  saque poupança => credito conta corrente.
  4. O saque da poupança é efetuado com sucesso , mas na hora de creditar a conta corrente o sistema caiu...
  5. A transação não foi completada pois o crédito do dinheiro na conta não foi efetuado.
  6. O sistema desfaz a operação de saque da poupança (credita novamente o valor) para não haver inconsistência na transação.

Nota: Veja os links abaixo onde as transações já foram analisadas sob a ótica da DAO e ADO.

Agora estamos em tempos de ADO.NET. Como ficou o enfoque ?

- Na ADO.NET você controla transações usando os objetos Connection e Transaction.

- Você pode iniciar uma transação local fazendo : Connection.BeginTransaction

- Após iniciar a transação você pode incluir um comando na transação usando a propriedade Transaction do objeto Command.

- O objeto Transaction é usado para consolidar (commit) ou desfazer (rollback) as modificações realizadas na fonte de dados com base no sucesso ou não  dos componentes da transação.

- Você pode também alistar em uma transação distribuída existente usando Connection.EnlistDistributedTransaction. Isto faz com que você tenha certeza de que se a transação for consolidada ou desfeita as modificações feitas pelo código na fonte de dados também serão consolidadas ou desfeitas.

Realizando um transação com ADO.NET

Os passos básicos necessários para realizar uma transação usando os objetos Connection e Transaction com  ADO.NET  são:

  1. Para marcar o início da transação chame o método BeginTransaction do objeto Connection. O método BeginTransaction retorna uma referência para Transaction e esta referência é atribuída para os objetos Command que são arrolados na transação.
  2. Atribua o objeto Transaction para a propriedade Transaction do Command que será executado. Se o Command é executado na conexão com uma Transaction ativa , e o objeto Transaction não foi atribuído para a propriedade Transaction do Command será disparada uma exceção.
  3. Execute os comandos requeridos
  4. Chame o método Commit do objeto Transaction para completar a transação ; ou chame o método RollBack para cancelar a transação.

Abaixo temos um código que mostra um exemplo de transação. Estou acessando o banco de dados Northwind.mdb , tabela - trasnportadoras - e estou incluindo dois registros na tabela. Estou efetuando o controle da transação e efetuando um commit ou rollback conforme o caso.

- Inicie um novo projeto no VS .NET do tipo Visual Basic e  template - Windows Application - e no formulário padrão insira um botão de comando .

- No evento click do botão digite o código a seguir.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

 

'define a string de conexão com o banco de dados

Dim strConn As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\teste\Nwind2002.mdb"

'define o objeto OledbConnection usando a string de conexão

Dim conexao As New OleDbConnection(strConn)

'abre a conexao

 

Try

   conexao.Open()

Catch ex As Exception

   MsgBox(ex.Message, MsgBoxStyle.Critical)

End Try

 

'inicia uma transação local

Dim Transacao As OleDbTransaction = conexao.BeginTransaction()

'Alista o command na transação atual.

Dim comando As OleDbCommand = conexao.CreateCommand()

comando.Transaction = Transacao

 

Try

     'define os comandos SQL para icluir dados na tabela Transportadoras do banco de dados Northwind.mdb

     comando.CommandText = "Insert into Transportadoras (CódigoDaTransportadora,NomeDaEmpresa,Telefone) VALUES (4, 'JcmSoft','(055)-658-55')"

     comando.ExecuteNonQuery()

     comando.CommandText = "Insert into Transportadoras (CódigoDaTransportadora,NomeDaEmpresa,Telefone) VALUES (5, 'Macorati','(061)-123-54')"

     comando.ExecuteNonQuery()

     'efetua o commit - consolida as inclusções

     Transacao.Commit()

     MsgBox("Foram incluídos dois registros na fonte de dados.", MsgBoxStyle.Exclamation, "Commit")

Catch ex As Exception

        Try

           'cancela a transacao - rollback

           Transacao.Rollback()

        Catch ex1 As OleDbException

           If Not Transacao.Connection Is Nothing Then

               MsgBox("Uma exceção do tipo " & ex1.GetType().ToString() & " foi encontrada durante a tentativa de cancelar a transação.", MsgBoxStyle.Critical, "RollBack")

           End If

        End Try

         MsgBox("Uma exceção do tipo " & ex.GetType().ToString() & " foi encontrada durante durante a inclusão de dados.", MsgBoxStyle.Critical, "Transações")

         MsgBox("Nenhum registro foi incluido na fonte de dados.", MsgBoxStyle.Critical, "RollBack")

Finally

'fecha a conexao com a fonte de dados

conexao.Close()

End Try

End Sub

Ao executar a aplicação teremos:

Como você pode verificar os dados foram incluídos na tabela.

Pois bem , se esta teoria estiver correta se ocorrer um erro após a inclusão dos dados na tabela deverá ocorrer um rollback na transação certo ?

Então eu vou provocar uma exceção incluindo a linha de código - Throw New System.Exception() - logo a após a execução dos comandos e antes de dar o Commit. Isto irá disparar uma exceção e deverá provocar um RollBack na transação. Abaixo um trecho do código modificado.

....

Try.

   'define os comandos SQL para icluir dados na tabela Transportadoras do banco de dados Northwind.mdb

   comando.CommandText = "Insert into Transportadoras (CódigoDaTransportadora,NomeDaEmpresa,Telefone) VALUES (6, 'JcmSoft','(055)-658-55')"

   comando.ExecuteNonQuery()

   comando.CommandText = "Insert into Transportadoras (CódigoDaTransportadora,NomeDaEmpresa,Telefone) VALUES (7, 'Macorati','(061)-123-54')"

   comando.ExecuteNonQuery()

 

   Throw New System.Exception()

 

   'efetua o commit - consolida as inclusções

   Transacao.Commit()

   MsgBox("Foram incluídos dois registros na fonte de dados.", MsgBoxStyle.Exclamation, "Commit")

Catch ex As Exception

    Try

       'cancela a transacao - rollback

       Transacao.Rollback()

    Catch ex1 As OleDbException

       If Not Transacao.Connection Is Nothing Then

       MsgBox("Uma exceção do tipo <<" & ex1.GetType().ToString() & ">> foi encontrada durante a tentativa de cancelar a transação.",     MsgBoxStyle.Critical, "RollBack")

       End If

     End Try

      MsgBox("Uma exceção do tipo <<" & ex.GetType().ToString() & ">> foi encontrada durante durante a inclusão de dados.",  MsgBoxStyle.Critical, "Transações")

      MsgBox("Nenhum registro foi incluido na fonte de dados.", MsgBoxStyle.Critical, "RollBack")

Finally

    'fecha a conexao com a fonte de dados

     conexao.Close()

End Try

...

Vamos executar e ...

Voilá ,  temos um rollback cancelando a transação. Conclusão : funciona.

Até mais ...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

 

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti