【问题标题】:Database and connections数据库和连接
【发布时间】:2010-10-01 18:23:29
【问题描述】:
我有兴趣了解数据库如何处理未由发起连接的实体明确关闭的连接。
假设我有一个一次只能接受 2 个并发连接的数据库。我有一段代码可以打开一个连接并且从不关闭它。这段代码永远运行,但它在其生命周期中只使用一次连接,但连接对象永远不会超出范围,因此它不会被垃圾收集。假设我运行此代码的 2 个实例。这是否意味着在程序终止或连接超时(由于不活动)之前,数据库不能接受更多的连接?
在上述场景中,如果连接对象被垃圾回收,那么连接是自动终止还是取决于我正在使用的数据库驱动程序,或者在我明确关闭它之前连接根本不会终止?
如果我在一段代码中打开一个连接并且我没有显式关闭连接,但程序终止了,那么数据库如何回收该连接?
【问题讨论】:
标签:
database
database-connection
【解决方案1】:
数据库连接的底层协议通常基于 TCP/IP。可以通过以下几种方式之一终止连接:
- 服务器优雅地关闭它并收到来自客户端的确认;
- 客户端正常关闭并收到来自服务器的确认;
- 连接超时。客户端和服务器分别由各自的操作系统告知连接已关闭;
- 连接被任一侧强制关闭。
在 (3) 的情况下,TCP 连接必须通过每隔一段时间发送虚拟消息来保持活动状态,以避免超时。您的连接可能会超时,因为双方都没有这样做(对于数据库连接,这不是您通常想要做的事情)。
完全有可能在一段时间内,一方认为连接已关闭,而另一方仍认为连接已打开。在这些情况下可能会发送消息(通常会被丢弃)。
每个连接(“套接字”)都使用一个称为文件描述符的操作系统资源(在 UNIX 术语中,您的操作系统可能称它为其他名称),它是 I/O 资源的句柄以及用于打开文件的相同内容(同样,操作系统可能会有所不同)。
您的数据库上的连接数限制将是以下各项中的最低值:
- 为操作系统配置的限制;
- 该进程允许的最大文件描述符(减去任何用于 I/O 活动的文件描述符);和
- (可能)有关连接限制的系统设置或策略。
如果连接不是基于 TCP 的(例如,在 UNIX 系统上经常与 MySQL 一起使用的文件系统套接字),原理实际上非常相似。
无论如何,这个故事的寓意是,数据库连接(无论其形式如何)都涉及某种操作系统资源。您的程序 hsa 直接或间接要求该资源。如果程序死了,操作系统将回收它(可能不是立即,而是最终)。如果连接被垃圾回收,那么资源将被释放,就像它被强制关闭一样。
它是保持连接打开并驱动任何限制的外部资源(而不是您的客户端正在使用的代码)。
【解决方案2】:
按顺序回答您的问题:
是的,可能。除非“并发连接”实际上是指“并发查询”。如果你保持数据库连接打开,它就是打开的。
垃圾收集可能会也可能不会清理连接。取决于所使用的语言和数据库驱动程序。 (垃圾收集可能仅限于回收内存,而不是 TCP 连接等资源。)
当您的程序终止时,通常操作系统会负责清理它使用的所有资源。这包括关闭 TCP 等连接。所以,对于大多数的连接类型,数据库都会被通知对方关闭了连接。