]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- add explciit section on engine disposal, fixes #3461
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 19 Jun 2015 15:49:49 +0000 (11:49 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 19 Jun 2015 15:50:18 +0000 (11:50 -0400)
(cherry picked from commit 3d78705cf4981e460d6d1b5bb08870286fc3fe93)

doc/build/core/connections.rst
lib/sqlalchemy/engine/base.py

index 6d7e7622f22bc0ba49ed381cf346bd69d6a67397..9dde5f0e184f742f9b128f0f85f7da5bfd4e6fd1 100644 (file)
@@ -368,6 +368,60 @@ the SQL statement. When the :class:`.ResultProxy` is closed, the underlying
 :class:`.Connection` is closed for us, resulting in the
 DBAPI connection being returned to the pool with transactional resources removed.
 
+.. _engine_disposal:
+
+Engine Disposal
+===============
+
+The :class:`.Engine` refers to a connection pool, which means under normal
+circumstances, there are open database connections present while the
+:class:`.Engine` object is still resident in memory.   When an :class:`.Engine`
+is garbage collected, its connection pool is no longer referred to by
+that :class:`.Engine`, and assuming none of its connections are still checked
+out, the pool and its connections will also be checked in, which has the
+effect of closing out the actual database connections as well.
+
+The :class:`.Engine` is intended to be a **long lived, typically permanent
+fixture throughout the lifespan of an application**.  It is **not** intended
+to be created and disposed on a per-connection basis.    However,
+in those cases where it is desirable that all connection resources
+referred to by the :class:`.Engine` need to be completely closed out,
+the :class:`.Engine` can be disposed using the :meth:`.Engine.dispose`
+method.   This disposes of the engine's underlying connection pool and
+replaces it with a new one that's empty.   Provided that the :class:`.Engine`
+is discarded at this point and no longer used, all checked-in connections
+which it refers to will also be fully closed.
+
+Valid use cases for calling :meth:`.Engine.dispose` include::
+
+ * When a program wants to release any remaining checked-in connections
+   held by the connection pool and expects to no longer be connected
+   to that database at all for any future operations.
+
+ * When a program uses multiprocessing or ``fork()``, and an
+   :class:`.Engine` object is copied to the child process,
+   :meth:`.Engine.dispose` should be called so that the engine creates
+   brand new database connections local to that fork.   Database connections
+   generally do **not** travel across process boundaries.
+
+ * Within test suites or multitenancy scenarios where many
+   ad-hoc, short-lived :class:`.Engine` objects may be created and disposed.
+
+
+
+
+Connections that are **checked out** are **not** discarded when the
+engine is disposed or garbage collected, as these connections are still
+strongly referenced elsewhere by the application.
+However, after :meth:`.Engine.dispose` is called, those
+connections are no longer associated with that :class:`.Engine`; when they
+are closed, they will be returned to their now-orphned connection pool
+which will ultimately be garbage collected, once all connections are checked in.
+Since this process is not as clean, it is strongly recommended that
+:meth:`.Engine.dispose` is called only after all checked out connections
+are fully checked in.
+
+
 .. _threadlocal_strategy:
 
 Using the Threadlocal Execution Strategy
index 2792cbe8cd2ec4eb9d272b1cdef05094a79920f8..847a68e0c7d3b039f24fe9cda9958247e01737fd 100644 (file)
@@ -1686,25 +1686,21 @@ class Engine(Connectable, log.Identified):
     def dispose(self):
         """Dispose of the connection pool used by this :class:`.Engine`.
 
+        This has the effect of fully closing all **currently checked in**
+        database connections.  Connections that are still checked out
+        will **not** be closed, however they will no longer be associated
+        with this :class:`.Engine`, so when they are closed individually
+        they will close out fully.
+
         A new connection pool is created immediately after the old one has
         been disposed.   This new pool, like all SQLAlchemy connection pools,
         does not make any actual connections to the database until one is
-        first requested.
-
-        This method has two general use cases:
+        first requested, so as long as the :class:`.Engine` isn't used again,
+        no new connections will be made.
 
-         * When a dropped connection is detected, it is assumed that all
-           connections held by the pool are potentially dropped, and
-           the entire pool is replaced.
-
-         * An application may want to use :meth:`dispose` within a test
-           suite that is creating multiple engines.
+        .. seealso::
 
-        It is critical to note that :meth:`dispose` does **not** guarantee
-        that the application will release all open database connections - only
-        those connections that are checked into the pool are closed.
-        Connections which remain checked out or have been detached from
-        the engine are not affected.
+            :ref:`engine_disposal`
 
         """
         self.pool.dispose()