过去的爆炸... 负责管理老化的 Access 2000 adp,用于管理驻留在 SQL 2005 服务器上的数据。在其中一个数据表单上,每当我尝试更改字段并将更改保存回数据库时,它都会在大约一分钟后超时。增加超时限制只会延迟超时错误消息的显示。我经历了所有常见的故障排除以确保兼容性(参见例如这个 SO question)。
这是设置:表单绑定到记录集(作为SELECT * FROM table_name
查询从数据库中读取。结果集的大小取决于表单上设置的过滤器,但结果通常约为 200 条记录(不是很多数据...)。表单上的某些字段会触发关联事件处理程序中的自动保存,如下所示:
Private Sub EndDate_Exit(Cancel As Integer)
some checking goes here...
...
DoCmd.RunCommand acCmdSaveRecord
End Sub
无论何时DoCmd.RunCommand acCmdSaveRecord
执行代码,ADP 都会冻结,直到出现超时错误。深入研究它,我查看了 SQL Server 上的活动监视器。acCmdSaveRecord
触发一条UPDATE
语句返回服务器以保存更改的数据。该语句本身是由 MS Access 根据基础表的主键自动构建的,该主键似乎定义正确。但是,更新被正在运行的SELECT
语句阻塞,这与SELECT * FROM table_name
上面提到的查询相对应。
这会导致死锁:用户的更改触发了一个UPDATE
,它被一个正在运行的程序阻塞SELECT
(看起来,它源于正在编辑的表单)。我怎样才能解决这个问题?
我们尝试过的事情:
- 我们已删除该
DoCmd.RunCommand acCmdSaveRecord
语句并将其替换为 codeMe.Dirty = False
,这会导致与上述完全相同的行为。 - 删除了
acCmdSaveRecord
完整的,并使用内置的访问菜单来保存更改。这是等效于#1 的功能,并导致完全相同的行为。 - 将
acCmdSaveRecord
调用替换为将更改保存到特定字段的存储过程。效果很好,除了从 GUI 保存整个记录(调用的保存按钮acCmdSaveRecord
)会导致相同的死锁。 - 将与表单关联的结果集的大小减少到几条记录。奇怪的是,仍然表现出完全相同的行为。