【问题标题】:msaccess odbc to sqlserver 2005 lock:timeoutms 访问 odbc 到 sql server 2005 锁定:超时
【发布时间】:2023-04-11 00:23:01
【问题描述】:

我已经让 msaccess 数据库使用“sql server”odbc 驱动程序通过链接表连接到 sql server。除了在交易方面,它大多运作良好。

我无法找到解决方法的问题是当 msaccess 表单决定在处理大型事务(10-30 秒)时自行刷新时发生的“锁定:超时”。

如果 msaccess 尝试访问被事务锁定的行,则 sql 分析器会立即显示 Lock:Timeout 但 MSAccess 无法处理此问题,并锁定应用程序直到其自己的 querytimeout 到期(60 秒)。愚蠢的是,它还暂停了 VBA,因此事务无法完成。

除了关闭这些批次期间打开的所有表单,我还能做什么?

如果我可以为 odbc 连接设置 mssql 锁定超时,则事务可能有机会完成,但似乎没有用于此的连接字符串参数。这很棘手,因为 MSAccess 的后台行为大部分是我无法控制的。而且我很确定没有可以为 sql 数据库设置的全局锁定超时。

有什么想法吗? 谢谢 卢克

【问题讨论】:

    标签: sql-server ms-access locking timeout odbc


    【解决方案1】:

    我没有使用 msaccess currentproject.connection,而是直接启动到 SQL 服务器的新 adodb 连接,然后设置锁定超时。例如 cnn.execute "set lock_timeout 1000"。那么这个连接会在锁超时过期时抛出一个错误——这个错误你可以捕捉到。这样做的缺点是您必须将 jet sql 转换为 tsql。好处是您可以将翻译后的 tsql 放入存储过程中并让它运行得更快。

    我发现了一些技巧,可以在您尝试完成事务之前最大限度地减少 msaccess 的锁定量。在开始事务之前放入 doevents 会有所帮助 - 它让控制权返回到 msaccess,因此它可以赶上它可能正在进行的任何异步刷新。

    在另一个例子中,我有一个计算列,在 me.refresh 之后需要很长时间(3-5 秒)来计算。我需要 me.refresh 并且正在寻找比禁用控件更好的解决方案。我发现如果在捕获锁定错误后继续重试事务,只要我在每个语句之间有一个 doevents,它就会在 5 次尝试内工作。然后我发现这个延迟通常会让 msaccess 完成它的事情。

    tt = Timer: Do While Timer - tt < 5: DoEvents: Loop
    

    这样做的问题是您不知道等待多长时间才足够。因为我不喜欢一遍又一遍地重试事务,所以我添加了一个可容忍的等待,这在大多数情况下就足够了,当它不是时,我将错误扔回给用户重试。

    我希望我有办法获得完成,放弃它的锁并保持一段时间的安静。

    【讨论】:

    • 这是否适用于 ODBC 链接表以及在它们之上创建的 DAO 记录集?
    • 我假设 DAO 是指在 msaccess 的当前连接中使用 dao。我真的不确定如何在这些上设置锁定超时。我相信 currentdb.querytimeout 在锁定超时发生后会很好地发挥作用。我正在使用六个自动化虚拟机对我的数据库进行压力测试,如果某些东西被另一个客户端锁定,我终生无法弄清楚如何及时使 msaccess 超时。我想这是另一个问题。尽管微软在 2006 年发表了 Andy Baron 的论文,但我开始怀疑 msaccess 和 odbc 在多用户环境中的可行性。
    • 嗯,有很多创建的 DAO 记录集不是在代码中显式创建的。例如,当您分配使用 ODBC 链接表的表单的记录集时,该表单的 .Recordset 属性就是一个 DAO 记录集。所以,我这里的问题是,ADO 超时设置与 Access 中根本不涉及 ADO 记录集的所有地方有什么关系(因为 ADO 不涉及数据访问)?
    • 至于可行性,这是我可能完全移动到服务器端的操作类型,因此不会有任何客户端超时。最初提问者的问题根本不常见——如果 ODBC 本身存在一些问题,那么会有更多的人遇到这类问题,不是吗?我自己从来没有遇到过,但是,我只有不到六个带有 SQL Server 后端的应用程序......
    • 我认为这看起来晦涩难懂(不常见)的原因可能是因为最佳实践通常涉及未绑定的表单和对断开连接的记录集的处理。就我而言,我使用绑定的 ODBC 链接表将 MSAccess DB 硬塞到 SQL 服务器上,尽可能少地修改应用程序(使用 50k 行 vba 和 sql)。
    【解决方案2】:

    我发现更好的方法是将 vba 计算结果发送到未绑定到任何 msaccess 接口对象的服务器端表,然后调用使用该表更新可能绑定的其他表的“最终化”过程.

    由于所有时间都在 vba 中并将结果发送到服务器,因此 finalization proc 很快,因此可以重复执行直到释放锁,客户端等待时间可以忽略不计。

    在服务器端表中存储前后数据允许检测在 vba 计算期间可能已被其他进程更改的行。这避免了长时间锁定任何东西的需要,这会在无法处理服务器的 lock:timeout 时增加 msaccess 冻结的风险。

    如果在 finalization proc 的事务(在 2k3 和 2k7 版本上确认)发生表单刷新,仍然会发生这种 msaccess 冻结,但它不能阻止此 proc 完成,因此更糟糕的是,会导致客户端延迟一分钟.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      相关资源
      最近更新 更多