The underlying protocol for database connections is typically TCP/IP based. The connection can be terminated in one of several ways:
- The server closes it gracefully and receives an acknowledgement from the client;
- The client closes is gracefully and receives an acknowledgement from the server;
- The connection times out. The client and server both separately are told by their respective operating systems that the connection has been closed;
- The connection is forcefully closed by either side.
In the case of (3), TCP connections must be kept alive by sending dummy messages every so often to avoid a timeout. Your connection may timeout because neither side is doing this (and for a database connection it's not something you typically want to do).
It's entirely possible for a time for one side to think the connection is closed and hte other side to still believe it is open. Messages may get sent in those cases (and typically discarded).
Each connection ("socket") uses an operating system resource called a file descriptor (in UNIX parlance, your OS may call it something else), which is a handle to an I/O resource and the same thing used for an open file (again, OSs may vary).
The limit on connections on your database will be the lowest of:
- The configured limit for the OS;
- The maximum file descriptors allowed for that process (minus any being used for I/O activity); and
- (possibly) system settings or policies on connection limits.
If the connection isn't TCP based (eg a filesystem socket as is often used with MySQL on UNIX systems) the principles are in fact very simlar.
Anyway, the moral of the story to take from this is that a database connection--regardless of its form--involves an operating system resource of some kind. Your program hsa directly or indirectly asked for that resource. If the program dies, the operating system will reclaim it (perhaps not immediately but eventually). If the connection gets garbage collected then the resource will be released in much the same way as if it had been forcibly closed.
Its that external resource (and not the code your client is using) that holds the connection open and drives any limits.