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#