我正在维护一个旧数据库,该数据库被用作另一个数据库的前端。为了总结这个前端正在做什么,它循环例如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
答案 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()