【问题标题】:Page-level locking in Jet 4.0 insert? "Can't update; currently locked" errorJet 4.0 插入中的页面级锁定? “无法更新;当前锁定”错误
【发布时间】:2011-02-21 23:31:15
【问题描述】:

在子表单上插入记录之前,我间歇性地收到此错误。

子表单处于“连续记录”模式。子表单recordsource是通过querydef.OpenRecordset打开的参数查询,在dbOpenDynaset模式下。

前端和后端使用 MS Access 2003、Access 2000 文件格式,FE 和 BE 都选择了记录级锁定,所有表单都为 RecordLocks 设置了“No Locks”。

google了一下,好像很多人都遇到过类似的情况,但是没有找到解决办法。

有什么想法吗?当在表单上完成插入时,似乎正在使用页面级锁定而不是记录级锁定。

  1. 会不会是后端连接(通过 DAO OpenDatabase)恢复到页面级锁定?如果是这样,DAO 连接字符串中的任何设置可能会有所帮助吗?

  2. 可能是通过 querydef 打开记录集,它使用页面级锁定,因此同时记录更新和记录插入(recordset.AddNew 或其他)可能会发生冲突?微软的文章here 暗示可能是这种情况(虽然不清楚,因为 OpenRecordset 应该没问题):

但是,从 ADO(当您使用 Microsoft Jet 4.0 OLE DB 提供程序时)、DAO 或 Access 查询用户运行的任何 SQL 数据操作语言 (DML) 查询(即添加、删除或修改记录的查询)界面将使用页面级锁定。页面级锁定用于 SQL DML 语句,以在您处理许多记录时提高性能。但是,即使打开了记录级锁定,它也不会用于更新备注字段中的值和索引字段中的值——它们仍然需要页面级锁定。

【问题讨论】:

  • 我一直在断言DAO使用页面级锁定而不能使用记录级锁定的基础上工作。就个人而言,我不认为记录级锁定有什么大不了的。乐观锁定极大地减少了用户之间的任何编辑冲突。您似乎正在更新您在子表单中打开的表。尝试更新时表单是否可能是脏的?
  • 外部表单没有绑定到任何记录集,因此它是子表单这一事实实际上并没有那么重要。我认为,发生这种情况的情况是,一个用户正在编辑现有记录,而另一个用户正在尝试输入新记录——此时第二个用户开始输入新记录(它运行 AddRec 或其他) .我将尝试在 OpenRecordset 中明确设置乐观锁定,但不要指望这会有所帮助,因为用户正在编辑不同的记录。我可以尝试禁用 AllowAdds 表单属性并使用插入查询手动执行。
  • 如果问题是由两个实际用户引起的,而不是由您自己锁定未保存编辑的页面,那么在 SQL 中执行插入根本不会改变任何内容。如果它被锁定,它被锁定。我认为这里还有其他事情发生,因为我在生产使用中从未遇到过乐观锁定时的页面锁定问题。
  • 哦,这很有趣.. 我凌晨 4 点被从床上拉起来去生产线工作.. 因为 jet 对于单用户来说不够可靠。回复:在乐观锁定下,我从未在生产使用中遇到过页面锁定问题。
  • 也许你的应用程序的问题,Aaron,不是 Jet,而是开发人员使用 Jet 的能力。

标签: ms-access locking jet


【解决方案1】:

这就是我认为问题的根源所在,也许是 Aaron 说 Jet “随机锁定记录”的原因。来自 DAO 文档:

Recordset.AddNew Method

注意当您在 Microsoft Jet 工作区中使用 AddNew 并且数据库引擎必须创建一个新页面来保存当前记录时,页面锁定是悲观的。如果新记录适合现有页面,则页面锁定是乐观的。

我想我在这个项目中看到的更多,因为它涉及在用户打开表单时经常插入大量记录,因此 db 引擎正在创建很多新页面,因此AddNew - 在表单上的 Insert 事件期间调用 - 更有可能恢复到悲观锁定,因此更有可能与同一页面上同时编辑的其他记录发生冲突。

我将建立一个测试平台,看看我的怀疑是否属实。

如果是这样,您似乎可以通过 not 使用 AddNew (AllowAdditions = False) 来避免它,而 而不是 通过查询插入新记录 + 刷新形成记录集。即使插入查询强制一个新页面,querydef.Execute 你也没有打开记录集,所以理论上应该没有锁定问题。

【讨论】:

  • 好吧,我设法在测试环境中重现了该错误(每 n 秒运行一次插入查询,而在单独的进程中每 m 秒执行 AddNew + Update)。而且我没有得到使用 querydef.Execute 与 AddNew 方式的错误。这就是好消息。但我确实经常遇到其他各种与并发相关的错误。
  • 所以我需要评估一个不同的后端以及除 Access 之外的其他选项。在短期内,我将更改接口以避免 AddNew,并设置一个错误处理程序,当并发错误被触发时重试 execute() 和 openrecordset()。如果有人想查看我的测试平台代码,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-14
相关资源
最近更新 更多