如何在ms-access中正确使用具有工作空间的事务

时间:2016-02-01 10:14:48

标签: ms-access access-vba

我正在维护一个旧数据库,该数据库被用作另一个数据库的前端。为了总结这个前端正在做什么,它循环例如10次,并调用子程序(让它命名为Parent)在默认工作空间中创建一个事务,然后该子程序调用另外5个子程序(让我们每个人调用Child)并且如果其中一个失败,理论上它会回滚事务,并将工作区对象设置为Nothing。

但是,我不确定每次都在工作,或者根本不工作。为了确定它是否正常工作,我创建了两个测试子例程,一个启动事务(Parent),并调用子子例程。两个子例程都试图在虚拟表中插入数据。当我需要启动回滚时,我将子子例程中的自定义错误引发到父子例程。经过多次实验,我注意到数据插入正确的唯一时间,或者当我提出错误时事务进行了回滚,只有当我在回滚之后并在将其设置为Nothing之前显式关闭工作空间对象时。我设法找到的唯一参考是here

正如您所理解的那样,我很困惑,因为这个数据库已经被用作前端多年,并且似乎设法插入数据。我还看到了Web上的代码示例,在提交或回滚事务之后,它们都没有关闭工作空间对象。

我主要担心的是,当出现错误时回滚无法正常工作,所以我试图找到更好的解决方案。

更新:添加了一些测试代码,只显示了事务提交 如果我包含wrk.Close语句,我只会在sys_test表中看到更改。否则,子例程将永远不会向表中添加数据,并且需要重新启动数据库,然后如果我添加wrk.Close并再次运行子例程,则会对表进行更改。

子子程序:

select 
  min(tstamp) as min_tstamp,
  max(tstamp) as max_tstamp,
  min(id1) as id1,
  min(id2) as id2
from
(
  select 
    grouped.*, 
    sum(newgroup) over (order by tstamp) as groupkey
  from
  (
    select 
      mytable.*, 
      case when id1 <> lag(id1) over (order by tstamp) 
             or id2 <> lag(id2) over (order by tstamp) 
      then 1 else 0 end as newgroup 
    from mytable
    order by tstamp
  ) grouped
)
group by groupkey
order by groupkey;

主要子程序:

Public Sub testChildTransaction()
On Error GoTo err
    CurrentDb.Execute "INSERT INTO sys_test (myName) VALUES ('Child');", dbFailOnError
exit_f:
    On Error GoTo 0
    Exit Sub
err:
    MsgBox "Error from Child"
    Resume exit_f
End Sub

1 个答案:

答案 0 :(得分:2)

这很奇怪。 git difftool <commit_id1> <commit_id2> 默认工作区,您不应该关闭它。通常,您只能使用DBEngine.Workspaces(0)关闭自己打开的工作区。

您的问题可能是由于您自己的工作区变量与DBEngine.CreateWorkspace混合而造成的,而CurrentDb不属于您的工作区(不太确定)。

当使用默认工作区(可能的回滚或性能)时,我总是使用一个单独的数据库变量,该变量被定义为工作区的“子”:

Dim WS As Workspace
Dim DB As Database

Set WS = DBEngine(0)
Set DB = WS.Databases(0)

WS.BeginTrans

DB.Execute "Stuff"    ' Not CurrentDb 

If "everything ok" Then
    WS.CommitTrans
Else
    WS.Rollback
End If

' With a local WS variable, even this is not necessary, but definitely no WS.Close here!
Set WS = Nothing

在您的情况下,您必须将DB声明为公共变量,或将其作为参数传递给testChildTransaction()