5

我们有多用户前端/后端 MS Access 2010 应用程序。我们添加了一个进程,当我们想在后端进行诸如压缩和修复之类的工作时,该进程将关闭远程前端。这是基于计时器的对表字段的检查,如果具有特定值将关闭应用程序。

我做了两次检查以查看用户是否连接到数据库:

  • 我有登录/注销过程,可以看到谁仍然登录(它的基于表单的所以是错误的,例如他们关闭表单但前端仍然打开)。

  • 我使用 .ldb 文件查看器查看是否仍有连接

两个问题:

  • 如果使用 ldb 查看器无法查看到 backed 的连接,是否有可能存在?

  • 是否有任何 100% 的防弹方法可以强制断开与后端的所有连接?

4

4 回答 4

6

用户将“锁”放入 LDB。LDB 是一种用于 MS Access 的锁数据库。

用户还把“锁”放在 LDB 和 MDB 上。这些锁是 Windows 和 Windows 网络提供的本地数据库原语的一部分。

如果ldb中没有锁,则用户没有写入 MDB。

如果mdb上没有锁,则用户没有使用该 Windows/网络服务。

要在 MDB 上获得独占锁定,您需要两者。MSAccess 不会让您在 LDB 具有显示其他人正在使用数据库的条目时进行排他锁,并且 Windows 不会在它具有显示其他人正在使用数据库的锁时为您提供排他锁。

要 100% 防弹清空 LDB,请删除 LDB。这就是为什么 Access 总是尝试在关闭时删除 LDB。如果 Access 崩溃,或网络断开,或 PC 或服务器关闭,LDB 将有尚未删除的数据(“锁”)。您可以通过删除 LDB 来摆脱它们。

如果用户在 LDB 上仍有 Windows/网络锁,则 Access 将无法删除 LDB。由于 Access 忽略了现有的“锁定”条目以清除损坏的“锁定”条目,这就是 Access/Windows 阻止 Access 在另一个用户仍在使用它时删除 LDB 的方式。

如果存在 Windows 锁或 Access/LDB“锁”,则您无法获得独占所有权。如果只存在 Access/LDB“锁”,您可以删除 LDB,然后获得独占所有权。

如果存在任何 Windows/网络锁,则您对 Access 所做的任何操作都不能让您断开其他人与网络的连接。您需要转到托管文件的服务器/PC,然后强制断开连接。Access 不是为您执行此操作的网络管理程序。

最后我看了一下,默认情况下,Windows Server 设置为在网络会话丢失 15 分钟后超时断开文件连接。因此,如果您关闭 PC,请等待 15 分钟,然后 Windows/网络锁定将解除(默认时间)。或者:管理工具、计算机管理、系统工具、共享文件夹、会话。选择要解锁的文件,然后删除会话。

于 2013-08-08T10:10:38.157 回答
6

存在一个修复程序,我已经为我维护的 MS-Access 应用程序安装了它。但是不方便,实现起来也不简单。

首先,关于锁定文件和锁定文件的一些背景知识。

锁定文件是一个有用的工具,但它是一个指示器,而不是实际的锁定:您可以编辑它,但没有任何效果。

如果实时 MS-Access 会话编辑数据、更改对象(例如:索引表)或执行维护任务,则可以在 .accdb 或 .mdb 后端数据库文件上保持文件锁定。该列表中的最后两项很少见 - 影响您在会话中打开的文件之外的另一个数据库文件需要一些努力,但有时会在野外观察到 - 但关闭这些会话应该释放锁定并且几乎总是将要。

崩溃的 MS-Access 会话可以保持对 .accdb 或 .mdb 后端数据库文件的文件锁定。强制重启有问题的机器应该释放锁,而且大部分都会释放。

您可以使用锁定文件(.ldb 或 .laccdb)跟踪那些

使用 ODBC 或 ADO 连接 Access 数据库的第三方报告应用程序应将其连接设置为只读,以便它们无法锁定文件。如果幸运的话,系统所有者使用您控制的 dsn 文件,您可以看到该设置。

一些报告应用程序,如 QLikView,是不透明的界面,需要完整的文件名,没有人知道接下来会发生什么:可能会锁定,也可能不会。你没有办法知道

一些报告应用程序 - 和 Excel 数据透视表 - 可能会链接到您的数据库,而所有者根本不会告诉您。如果他们的连接配置错误,他们可以在检索时锁定您的表:并且终止客户端会话可以使锁定保持在原位。无聊的 Excel 用户一直在观看缓慢的枢轴“刷新”。

更糟糕的是,一些第三方系统可能需要写入数据:应该避免这种情况 - 通过 Access 客户端应用程序!- 但你并不总是能做出那个决定。

如果幸运的话,连接对象配置正确,因此机器 ID 在连接字符串中,确保它会出现在锁定文件中,并允许您找到带有锁的机器......

也许他们会这样做:通常他们不会。

...请注意,对于您关心的问题,行锁定查询、页面锁定查询和表锁定查询在功能上是相同的:如果您需要在“文件”级别执行某些操作(如压缩和修复),该文件已锁定您。在该锁被释放之前,您将被锁定。

您可能无法识别机器。您可能会也可能无法强制他们离开网络。它们在正常操作中可能会或不会成功释放锁,如果它们崩溃,它们几乎肯定不会。

所以:这不是一张漂亮的照片。

在公司环境中,您最好的解决方案是使用“手指”工具直接与网络管理员联系,以确定谁在锁定数据库文件、联系用户的能力以及断开有问题的会话的能力。

失效模式有:

  • 如果您的组织结构不允许您建立这种沟通渠道,那您就完蛋了。
  • 如果您组织的网络管理员没有能力或权限在有用的时间范围内执行此操作,那么您就完蛋了。
  • 如果您组织的网络管理员选择不这样做,那您就完蛋了。

但是,我确实为我的 MS-Access 应用程序进行了修复:

我使用的解决方法非常激进 - 不是将铁锹穿过建筑物的电源的“核选项”,或者屈服于系统管理员对人类牺牲的要求,但是非常不愉快并且实施大量荒谬的工作:

  1. 配置客户端 - 您的 MS-Access 前端应用程序 - 在命名的后端数据库之间轻松切换。
  2. 同样,您编写并允许其他应用程序使用的 dsn 文件应该可以由预先存在的脚本访问,以将“DBQ=”或“数据源=”子句编辑为新文件名。
  3. 获取数据库文件的副本,将其保存到本地临时文件夹以进行所需的维护工作,然后以新名称将其重新发布到应用程序的“数据”文件夹中。
  4. 现在运行“更改后端”脚本或 VBA 函数...
  5. ......还有其他任何使用旧的、锁定的后端文件的人。

提示:实现您的前端应用程序,以便它定期轮询后端数据库(或其他一些资源,您最坏的情况是完全锁定)以执行“维护关闭”或“更改数据库”指令是明智的放入您的“主菜单”表单的计时器事件。

此外,还有代码可以自动切换链接表的源数据库。

于 2016-03-17T12:22:44.300 回答
3

如果使用 ldb 查看器无法查看到 backed 的连接,是否有可能存在?

是的,我曾多次遇到后端被锁定的问题,但我用 ldb 查看器看不到任何东西。在这些情况下,我们甚至对用户访问数据库的机器进行了硬关机。糟糕的解决方案,但在需要的时候,你有时会绝望。

是否有任何 100% 的防弹方法可以强制断开与后端的所有连接?

不,我还没有找到 100% 的方法来强制所有人退出后端数据库。我发现最接近完美的是使用位于 Utter Access 上的 Chris Symonds Timeout-Force Out 代码

该数据库完成多项任务:

  1. 允许开发人员使用 db 去任何 PC 并强制所有用户关闭拆分 db,以便开发人员可以独占打开 db 以修改/维护 db。
  2. 如果用户在开发人员设置的指定分钟数内未使用 db,则将用户踢出 db。
  3. 允许开发人员每天指定一个时间来强制所有用户关闭拆分数据库并关闭数据库以进行备份、编译或其他操作。
  4. 所有功能都是可选的,无需额外编码即可绕过,仅使用每个数据库所需的功能。

我实现了他的代码,它在大约 99% 的时间里都能正常工作,但在某些情况下,MS Access 还是有点棘手,我看不出为什么数据库被锁定或强制所有人退出。

于 2012-06-05T23:09:59.543 回答
3

我做了两次检查,看看用户是否连接到数据库

如果您需要独占打开数据库,您可以跳过其他检查,只需检查您是否可以这样做。

Public Function CheckExclusive(ByVal pFullPath As String) As Boolean
    Dim blnReturn As Boolean
    Dim cn As Object
    Dim strConnection As String

On Error GoTo ErrorHandler

    strConnection = "Provider=" & _
        CurrentProject.Connection.Provider & _
        ";Data Source=" & pFullPath & ";"
    Set cn = CreateObject("ADODB.Connection")
    cn.Mode = 12& ' adModeShareExclusive '
    cn.Open strConnection
    blnReturn = True
    cn.Close

ExitHere:
    On Error Resume Next
    Set cn = Nothing
    On Error GoTo 0
    CheckExclusive = blnReturn
    Exit Function

ErrorHandler:
    blnReturn = False
    GoTo ExitHere
End Function

然后使用 db 文件的完整路径调用该函数。

If CheckExclusive("C:\SomeFolder\YourDb.mdb") = True Then
    ' do what you need here which requires exclusive access: '
    '     make backup; compact; whatever '
End If
于 2012-06-05T23:58:14.527 回答