如何检查连接池是否被清除

How to check if connection pools are cleared

我想重命名数据库文件,甚至每次我必须调用时都使用 using 连接:

FirebirdSql.Data.FirebirdClient.FbConnection.ClearAllPools();

问题是此方法不会阻塞线程,我不知道如何检查是否所有连接都已清除,因为如果我从以下位置获取值:

FirebirdSql.Data.FirebirdClient.FbConnection.ConnectionPoolsCount

方法后立即为零,但我仍然无法重命名数据库文件。如果我在该方法之后设置了一些超时(我尝试了 1 秒),那么文件不会被锁定,我可以重命名它。问题是这个超时在不同的机器上肯定是不同的。

FWIK 如何检查文件是否未锁定的唯一其他方法是尝试在超时循环中重命名,但我无法确定锁定是由来自我的应用程序的连接还是来自某个地方否则。
那么有没有更好的方法,我怎么能等到这个方法清除连接?

如果我负责维护 firebird 提供程序,我不希望用户依赖此类功能。

其他应用程序可以打开该文件(您只能控制当前 AppDomain 中的连接池),并且服务器可能 运行 对数据库进行某种维护。

因此,即使您可以等待池被清除,我认为如果您真的不得不处理这些文件,一个更强大的解决方案是改为停止 firebird 服务(并等待它完全停止)。

为了格式化列表而将其作为答案。

@Artholl 出于多种原因,您不能安全地依赖自己的断开连接。

  1. 可能连接了其他程序,而不仅仅是您的 运行 程序。并且除非您使用 SYSDBA 或数据库创建者或 RDB$ADMIN 角色连接 - 您现在无法查询是否有其他连接。 但是,您可以从 MON$ATTACHMENTS 查询与您的 CURRENT_CONNECTION 相同用户建立的连接。这可能会帮助您检查应用程序自己的池的状态。只是没什么实用价值

  2. Firebird 3在SuperServer模式下有LINGER参数,意思是服务器会在最后一个客户端断开连接后保持数据库打开一段时间,期望如果有新客户端决定连接DB 文件的 PAGE CACHE 已经存在。类似于中等负载的 WWW 服务器。

  3. 即使在 Firebird 2 中,每个打开的数据库都有一些缓存,缓存的大小取决于安装(firebird.conf)和数据库特定(gfix/gstat) .在引擎看到所有客户端断开连接后决定关闭数据库 - 它从刷新缓存开始并要求 OS 也刷新它们的缓存(没有通用的独立于硬件的方法来要求 RAID 控制器和磁盘本身刷新缓存,否则 Firebird 也会尝试这样做)。默认情况下,Firebird 缓存很小,将它们抢占到硬件层应该很快,但仍然不是即时的。

  4. 即使您检查所有其他客户端确实断开连接,然后您自己断开连接,然后您猜对了灵儿和缓存要等多久,即使那样你仍然不安全。您受制于 竞争条件 。在你开始做一些需要明确拥有数据库的事情的时候,可能会出现一些新的客户端同时打开他的新连接。

因此,正确的方法不仅是证明现在没有数据库连接,而且还要确保将来不会有任何新连接,直到您重新启用它。

因此,正如 Mark 上面所说,您必须使用 Shutdown 方法使数据库进入不允许连接的状态。在完成文件重命名和其他操作后 - 将其切换回正常模式。

https://www.firebirdsql.org/file/documentation/reference_manuals/user_manuals/html/gfix-dbstartstop.html