使用事务(BeginTrans/CommitTrans/Rollback)后,MS-Access 2010 环境似乎不稳定。我所说的不稳定是指 MS-Access 环境不再允许任何对象修改(它会自动变成一种独占模式),或者在运行进程的任何 SQL 查询时显示意外的错误消息。
情况:
我有一个 MS-Access 2010 数据库(accdb
格式),我在其中添加了一个新的 VBA 模块。该模块处理给定文件,以便将其记录加载到数据库的表中。我使用 MS-Access 2010 环境来处理此数据库(不是单独的应用程序)
对于每条记录,在将其存储到数据库之前都会进行一些验证。如果检测到任何错误,所有处理都会被取消。我使用事务来确保完整的文件正常并加载。
Problem:
如果我第一次运行此进程时它是正确的,因此它以 COMMIT 结束,则可以使用其他文件重新运行该进程,而不管其处理结果如何。每次处理的结果仅取决于文件中数据的质量。
但是,如果我第一次运行此进程时它会以 ROLLBACK 结束,则该进程的每次下一次运行都会在进程中执行任何 SQL 查询时以错误结束。
在这两种情况下,MS-Access环境都变成一种独占模式。
问题:
这种 VBA 模块或处理是否符合 MS-Access 2010 开发环境?或者我应该构建一个新的单独应用程序来连接到我的 Access 数据库来运行我的文件处理。
代码(简化):
Private Sub Comando0_Click() 'A success processing simulation
On Error GoTo ErrManagenent
BeginTrans
'Some procesing finishin OK
ProcessWithoutError
CommitTrans
Exit Sub
ErrManagenent:
Debug.Print "Comando0_Click Error: " & Err.Description & "." & vbCrLf & Err.Source
Rollback
End Sub
Private Sub Comando6_Click() 'A fail processing simulation.
On Error GoTo ErrManagenent
BeginTrans
'Some procesing finishin with a Err.Raise
ProcessWithError
Exit Sub
ErrManagenent:
Debug.Print "Comando6_Click Error: " & Err.Description & "." & vbCrLf & Err.Source
Rollback
End Sub
Private Sub ProcessWithError() 'simulation of a process ending with error
Dim rs As Recordset
Dim strSql As String
'Any DB query.
strSql = "SELECT * FROM 00_Bancos"
Set rs = CurrentDb.OpenRecordset(strSql)
Debug.Print rs.RecordCount
'some processing with
'......
'let's suppose there is an error while processing
rs.Close
Err.Raise 11, , "MY error mesage"
End Sub
Private Sub ProcessWithoutError() 'Simulation of a process ending OK
Dim rs As Recordset
Dim strSql As String
'Any DB query.
strSql = "SELECT * FROM 00_Bancos"
Set rs = CurrentDb.OpenRecordset(strSql)
Debug.Print rs.RecordCount
'some processing
'......
'let's suppose the process finishes OK.
rs.Close
End Sub
仅当您要插入/更新多个 SQL 语句(这对回滚有意义)时,才应使用事务。还可以在 SQL 执行之前使用事务并捕获错误来找出哪个 SQL 语句触发了失败。
pseudo:
- 进行验证
- 准备SQL语句
- 准备SQL语句2
- 开始交易
- 执行SQL语句
- 提交或回滚
在代码中它将是:
Private Sub mTrans()
Dim myDB As DAO.Database
Set myDB = CurrentDb
Dim SQL_SET As String
SQL_SET = "First sql statement"
On Error GoTo ERROR_SQL1:
DBEngine.BeginTrans
myDB.Execute SQL_SET, dbFailOnError
On Error GoTo ERROR_SQL2:
SQL_SET = "second sql statement..." 'either use the same variable or use SQL_SET1 for better overview
myDB.Execute SQL_SET, dbFailOnError
DBEngine.CommitTrans
EXIT_SUB:
On Error Resume Next
Set myDB = Nothing
Exit Sub
ERROR_SQL1:
DBEngine.Rollback
MsgBox "Error while executing sql_1. " & vbNewLine & "System msg: " & Err.description
GoTo EXIT_SUB
ERROR_SQL2:
DBEngine.Rollback
MsgBox "Error while executing sql_2. " & vbNewLine & "System msg: " & Err.description
GoTo EXIT_SUB
End Sub
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)