ADO - Usando Transações - BeginTrans, CommitTrans e RollBack.
Os conceitos básicos sobre transações já foram estudados no artigo O Processamento de Transações: BeginTrans, CommitTrans e RollBack. Neste breve artigo iremos mostrar como usar as transações com a tecnologia ADO.
O projeto básico consiste de um único formulário mostrado a seguir:
Neste Projeto Temos os seguintes
Controles:
|
O banco de dados que utilizamos é o Nwind.mdb que vem junto com o Visual Basic . Criamos uma tabela(veja como fazer isto em : Criando um banco de dados e uma tabela para armazenar suas informações) chamada contas neste banco de dados com a seguinte estrutura:
A tabela contas que criamos no banco de dados Nwind.mdb e que copiamos para o diretório c:\teste. |
Como funciona o projeto
O projeto funciona da seguinte maneira:
Vejamos o projeto em tempo de execução :
O Código do projeto segue abaixo:
Option Explicit Private mConn As Connection Private Sub Command1_Click() Dim lRowsAffected As Long Dim sError As String Dim sCmd As String Dim rs As Recordset If vbYes = MsgBox("Transferir " _ & Format(Val(maskvalor.Text), "$#,##0.00;($#,##0.00)") _ & " De -> " & listfrom.SelectedItem.Text _ & " Para -> " & listto.SelectedItem.Text & ".", vbYesNo) Then 'iniciando a transação mConn.BeginTrans On Error GoTo TransferFailure 'usar o método execute do objeto Connection sCmd = "UPDATE contas" sCmd = sCmd & " SET saldo = saldo - " & CCur(maskvalor.Text) ' atualize somente se a conta de origem tiver saldo suficiente sCmd = sCmd & " WHERE saldo >= " & CCur(maskvalor.Text) sCmd = sCmd & " AND AccountId = " _ & Right(listfrom.SelectedItem.Key _ , Len(listfrom.SelectedItem.Key) - 1) mConn.Execute sCmd, lRowsAffected, adExecuteNoRecords If lRowsAffected = 0 Then sError = " Saldo insuficiente para realizar transferência..." GoTo TransferFailure End If 'ou use os métodos do objeto recordset Set rs = New Recordset rs.Open "SELECT * FROM contas WHERE AccountId = " _ & Right(listto.SelectedItem.Key _ , Len(listto.SelectedItem.Key) - 1), mConn, _ adOpenDynamic, adLockPessimistic rs!saldo = rs("saldo") + Val(maskvalor.Text) rs.Update 'parece que tudo ocorreu bem , vamos salvar(commit) a transação mConn.CommitTrans rs.Close End If TransferDone: 'deu tudo certo então atualiza os controles listview On Error GoTo 0 Set rs = Nothing RefreshLists Exit Sub TransferFailure: 'alguma coisa deu errado , vamos cancelar(rollback) a transação mConn.RollbackTrans Dim ADOError As Error For Each ADOError In mConn.Errors sError = sError & ADOError.Number & " - " & _ ADOError.Description & vbCrLf Next ADOError MsgBox sError End Sub Private Sub Command2_Click() Unload Me End Sub Private Sub Form_Activate() maskvalor.SetFocus End Sub Private Sub Form_Load() 'Abrindo uma conexão Set mConn = New Connection mConn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=c:\teste\nwind.mdb" RefreshLists End Sub Private Sub Form_Unload(Cancel As Integer) mConn.Close Set mConn = Nothing End Sub Private Sub RefreshLists() 'atualizando os controles com os saldos Dim NewItem As ListItem Dim rs As Recordset Set rs = New Recordset listfrom.ListItems.Clear listto.ListItems.Clear rs.Open "contas", mConn, adOpenForwardOnly, adLockReadOnly Do Until rs.EOF Set NewItem = listfrom.ListItems.Add(, "k" & rs("AccountId"), rs("Name")) NewItem.SubItems(1) = Format(rs("saldo"), "$0.00") Set NewItem = listto.ListItems.Add(, "k" & rs("AccountId"), rs("Name")) NewItem.SubItems(1) = Format(rs("saldo"), "$0.00") rs.MoveNext Loop rs.Close Set rs = Nothing End Sub Private Sub maskvalor_GotFocus() maskvalor.SelStart = 0 maskvalor.SelLength = Len(maskvalor.Text) End Sub Private Sub maskvalor_KeyPress(KeyAscii As Integer) Select Case KeyAscii Case 8, 48 To 57, 127 Case 46 KeyAscii = 44 Case 13 'Simula o pressionamento da tecla TAB SendKeys "{tab}" 'A linha a seguir evita ouvir um bip KeyAscii = 0 Case Else KeyAscii = 0 End Select End Sub |
Observe que usamos dois métodos da ADO para atualizar os dados:
Usando SQL - instrução UPDATE e o método Execute
sCmd = "UPDATE contas" sCmd = sCmd & " SET saldo = saldo - " & CCur(maskvalor.Text) 'atualize somente se a conta de origem tiver saldo suficiente sCmd = sCmd & " WHERE saldo >= " & CCur(maskvalor.Text) sCmd = sCmd & " AND AccountId = " _ & Right(listfrom.SelectedItem.Key _ , Len(listfrom.SelectedItem.Key) - 1) mConn.Execute sCmd, lRowsAffected, adExecuteNoRecords |
Usando o método Update da ADO
Set rs = New Recordset rs.Open "SELECT * FROM contas WHERE AccountId = " _ & Right(listto.SelectedItem.Key _ , Len(listto.SelectedItem.Key) - 1), mConn, _ adOpenDynamic, adLockPessimistic rs!saldo = rs("saldo") + Val(maskvalor.Text) rs.Update |
A rotina que atualiza os controles de lista(ListView) é:
Do Until rs.EOF Set NewItem = listfrom.ListItems.Add(, "k" & rs("AccountId"), rs("Name")) NewItem.SubItems(1) = Format(rs("saldo"), "$0.00") Set NewItem = listto.ListItems.Add(, "k" & rs("AccountId"), rs("Name")) NewItem.SubItems(1) = Format(rs("saldo"), "$0.00") rs.MoveNext Loop |
Os métodos : BeginTrans , CommitTrans e RollBack estão destacados no código.
Bem , acho que é só isto . Legal este projeto né.. ?
Você pode recortar e copiar a vontade.
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:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#