C
Colin
There seems to be a serious problem with transaction rollbacks using DAO 3.6
or 3.51 on Access databases. I have written a minimal VB6 application and
would be grateful if anyone could confirm the problem and, if possible, a fix.
The problem is that the recordset is "losing" records after the transaction
rollback when nothing has been done to change the recordset.
To test this:
1. Create a new Access database with one table (Table1) in it. The table
only needs one (Autonumber) column in it called RecordID. Populate the table
with at least 2 records.
2. Create a new VB6 project in the same folder as the table. Create a
default form and put one command button on it called cmdGo
3. Copy the code below into the form and run the project...you should end up
with the following in the debug window: "open, ID 1 found, begintrans, ID 2
found, rollback, ID 2 not found, requery, ID 2 found, close".
Note: I am using the XP SP2 version of DAO360.dll. I have also tested this
application with DAO3.51 and get the same results. The database is Access 97
but I get the same results with an Access 2000 database.
If you look at the code and take out all the debug print stuff you'll see it
is incredibly simple.
---------------------------------------------------------------------------------------
Option Explicit
Dim db As DAO.Database
Dim wrk As DAO.Workspace
Private Sub Form_Load()
'Open default workspace and the database...The database has one table
called Table1.
'This table has one field called RecordID and the field is an
AutoNumber. There are
'2 records in the table.
Set wrk = Workspaces(0)
Set db = Workspaces(0).OpenDatabase(App.Path & "\" & "Test.mdb", False,
False)
End Sub
Private Sub cmdGo_Click()
Dim rst As DAO.Recordset
Dim strMessage As String
Dim lngID As Long
'Open a simple recordset
Set rst = db.OpenRecordset("SELECT * FROM Table1", dbOpenDynaset,
dbInconsistent, dbOptimistic): strMessage = "open, "
'Find the first record - OK
lngID = 1
rst.FindFirst "RecordID=" & lngID: strMessage = strMessage & "ID " &
lngID & IIf(rst.NoMatch, " not found", " found") & ", "
'Begin a transaction and find the second record - OK
wrk.BeginTrans: strMessage = strMessage & "begintrans, "
lngID = 2
rst.FindFirst "RecordID=" & lngID: strMessage = strMessage & "ID " &
lngID & IIf(rst.NoMatch, " not found", " found") & ", "
'Rolback the transaction
wrk.Rollback: strMessage = strMessage & "rollback, "
'Look for second record NOT OK...requery, find second record OK
rst.FindFirst "RecordID=" & lngID: strMessage = strMessage & "ID " &
lngID & IIf(rst.NoMatch, " not found", " found") & ", "
rst.Requery: strMessage = strMessage & "requery, "
rst.FindFirst "RecordID=" & lngID: strMessage = strMessage & "ID " &
lngID & IIf(rst.NoMatch, " not found", " found") & ", "
'Tidy up
rst.Close: strMessage = strMessage & " close"
'Print what we found
Debug.Print strMessage
End Sub
or 3.51 on Access databases. I have written a minimal VB6 application and
would be grateful if anyone could confirm the problem and, if possible, a fix.
The problem is that the recordset is "losing" records after the transaction
rollback when nothing has been done to change the recordset.
To test this:
1. Create a new Access database with one table (Table1) in it. The table
only needs one (Autonumber) column in it called RecordID. Populate the table
with at least 2 records.
2. Create a new VB6 project in the same folder as the table. Create a
default form and put one command button on it called cmdGo
3. Copy the code below into the form and run the project...you should end up
with the following in the debug window: "open, ID 1 found, begintrans, ID 2
found, rollback, ID 2 not found, requery, ID 2 found, close".
Note: I am using the XP SP2 version of DAO360.dll. I have also tested this
application with DAO3.51 and get the same results. The database is Access 97
but I get the same results with an Access 2000 database.
If you look at the code and take out all the debug print stuff you'll see it
is incredibly simple.
---------------------------------------------------------------------------------------
Option Explicit
Dim db As DAO.Database
Dim wrk As DAO.Workspace
Private Sub Form_Load()
'Open default workspace and the database...The database has one table
called Table1.
'This table has one field called RecordID and the field is an
AutoNumber. There are
'2 records in the table.
Set wrk = Workspaces(0)
Set db = Workspaces(0).OpenDatabase(App.Path & "\" & "Test.mdb", False,
False)
End Sub
Private Sub cmdGo_Click()
Dim rst As DAO.Recordset
Dim strMessage As String
Dim lngID As Long
'Open a simple recordset
Set rst = db.OpenRecordset("SELECT * FROM Table1", dbOpenDynaset,
dbInconsistent, dbOptimistic): strMessage = "open, "
'Find the first record - OK
lngID = 1
rst.FindFirst "RecordID=" & lngID: strMessage = strMessage & "ID " &
lngID & IIf(rst.NoMatch, " not found", " found") & ", "
'Begin a transaction and find the second record - OK
wrk.BeginTrans: strMessage = strMessage & "begintrans, "
lngID = 2
rst.FindFirst "RecordID=" & lngID: strMessage = strMessage & "ID " &
lngID & IIf(rst.NoMatch, " not found", " found") & ", "
'Rolback the transaction
wrk.Rollback: strMessage = strMessage & "rollback, "
'Look for second record NOT OK...requery, find second record OK
rst.FindFirst "RecordID=" & lngID: strMessage = strMessage & "ID " &
lngID & IIf(rst.NoMatch, " not found", " found") & ", "
rst.Requery: strMessage = strMessage & "requery, "
rst.FindFirst "RecordID=" & lngID: strMessage = strMessage & "ID " &
lngID & IIf(rst.NoMatch, " not found", " found") & ", "
'Tidy up
rst.Close: strMessage = strMessage & " close"
'Print what we found
Debug.Print strMessage
End Sub