summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/pool.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-11-22 23:45:24 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2012-11-22 23:45:24 -0500
commit0f0ce7c9b7c4b3a9f1329dfa9c42d0d69386d48f (patch)
treed50620cff987eeb763c96bb24b7c62558dab95a7 /lib/sqlalchemy/pool.py
parent0c9eb439267fc48e38a1390acf0eaa34d939867a (diff)
downloadsqlalchemy-0f0ce7c9b7c4b3a9f1329dfa9c42d0d69386d48f.tar.gz
- recognize that do_rollback() and do_commit() work with a DBAPI connection,
whereas the other do_rollback_twophase(), savepoint etc. work with :class:`.Connection`. the context on these are different as twophase/savepoint are available at the :class:`.Connection` level, whereas commit/rollback are needed at a lower level as well. Rename the argument to "dbapi_connection" when the conneciton is in fact the DBAPI interface. - start thinking about being able to track "autocommit" vs. "commit", but not sure we have a need for this yet. - have Pool call out to a Dialect for all rollback/commit/close operations now. Pool no longer calls DBAPI methods directly. May use this for a workaround for [ticket:2611] - add a new Pool event reset() to allow the pool's reset of the connection to be intercepted. - remove methods in Informix dialect which appear to be hardcoding some isolation settings on new Transaction only; the isolation API should be implemented for Informix. also removed "flag" for transaction commit/rollback being not available; this should be based on server/DBAPI version and we will need someone with test access in order to help determine how this should work
Diffstat (limited to 'lib/sqlalchemy/pool.py')
-rw-r--r--lib/sqlalchemy/pool.py76
1 files changed, 50 insertions, 26 deletions
diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py
index 5518b1e22..368cf9d6f 100644
--- a/lib/sqlalchemy/pool.py
+++ b/lib/sqlalchemy/pool.py
@@ -65,10 +65,29 @@ reset_rollback = util.symbol('reset_rollback')
reset_commit = util.symbol('reset_commit')
reset_none = util.symbol('reset_none')
+class _ConnDialect(object):
+ """partial implementation of :class:`.Dialect`
+ which provides DBAPI connection methods.
+
+ When a :class:`.Pool` is combined with an :class:`.Engine`,
+ the :class:`.Engine` replaces this with its own
+ :class:`.Dialect`.
+
+ """
+ def do_rollback(self, dbapi_connection):
+ dbapi_connection.rollback()
+
+ def do_commit(self, dbapi_connection):
+ dbapi_connection.commit()
+
+ def do_close(self, dbapi_connection):
+ dbapi_connection.close()
class Pool(log.Identified):
"""Abstract base class for connection pools."""
+ _dialect = _ConnDialect()
+
def __init__(self,
creator, recycle=-1, echo=None,
use_threadlocal=False,
@@ -76,7 +95,8 @@ class Pool(log.Identified):
reset_on_return=True,
listeners=None,
events=None,
- _dispatch=None):
+ _dispatch=None,
+ _dialect=None):
"""
Construct a Pool.
@@ -152,6 +172,8 @@ class Pool(log.Identified):
self.echo = echo
if _dispatch:
self.dispatch._update(_dispatch, only_propagate=False)
+ if _dialect:
+ self._dialect = _dialect
if events:
for fn, target in events:
event.listen(self, target, fn)
@@ -164,6 +186,16 @@ class Pool(log.Identified):
dispatch = event.dispatcher(events.PoolEvents)
+ def _close_connection(self, connection):
+ self.logger.debug("Closing connection %r", connection)
+ try:
+ self._dialect.do_close(connection)
+ except (SystemExit, KeyboardInterrupt):
+ raise
+ except:
+ self.logger.debug("Exception closing connection %r",
+ connection)
+
@util.deprecated(
2.7, "Pool.add_listener is deprecated. Use event.listen()")
def add_listener(self, listener):
@@ -296,14 +328,7 @@ class _ConnectionRecord(object):
def close(self):
if self.connection is not None:
- self.__pool.logger.debug("Closing connection %r", self.connection)
- try:
- self.connection.close()
- except (SystemExit, KeyboardInterrupt):
- raise
- except:
- self.__pool.logger.debug("Exception closing connection %r",
- self.connection)
+ self.__pool._close_connection(self.connection)
def invalidate(self, e=None):
if e is not None:
@@ -335,15 +360,7 @@ class _ConnectionRecord(object):
return self.connection
def __close(self):
- try:
- self.__pool.logger.debug("Closing connection %r", self.connection)
- self.connection.close()
- except (SystemExit, KeyboardInterrupt):
- raise
- except Exception, e:
- self.__pool.logger.debug(
- "Connection %r threw an error on close: %s",
- self.connection, e)
+ self.__pool._close_connection(self.connection)
def __connect(self):
try:
@@ -365,13 +382,15 @@ def _finalize_fairy(connection, connection_record, pool, ref, echo):
if connection is not None:
try:
+ if pool.dispatch.reset:
+ pool.dispatch.reset(connection, connection_record)
if pool._reset_on_return is reset_rollback:
- connection.rollback()
+ pool._dialect.do_rollback(connection)
elif pool._reset_on_return is reset_commit:
- connection.commit()
+ pool._dialect.do_commit(connection)
# Immediately close detached instances
if connection_record is None:
- connection.close()
+ pool._close_connection(connection)
except Exception, e:
if connection_record is not None:
connection_record.invalidate(e=e)
@@ -556,7 +575,8 @@ class SingletonThreadPool(Pool):
echo=self.echo,
logging_name=self._orig_logging_name,
use_threadlocal=self._use_threadlocal,
- _dispatch=self.dispatch)
+ _dispatch=self.dispatch,
+ _dialect=self._dialect)
def dispose(self):
"""Dispose of this pool."""
@@ -768,7 +788,8 @@ class QueuePool(Pool):
recycle=self._recycle, echo=self.echo,
logging_name=self._orig_logging_name,
use_threadlocal=self._use_threadlocal,
- _dispatch=self.dispatch)
+ _dispatch=self.dispatch,
+ _dialect=self._dialect)
def dispose(self):
while True:
@@ -841,7 +862,8 @@ class NullPool(Pool):
echo=self.echo,
logging_name=self._orig_logging_name,
use_threadlocal=self._use_threadlocal,
- _dispatch=self.dispatch)
+ _dispatch=self.dispatch,
+ _dialect=self._dialect)
def dispose(self):
pass
@@ -881,7 +903,8 @@ class StaticPool(Pool):
reset_on_return=self._reset_on_return,
echo=self.echo,
logging_name=self._orig_logging_name,
- _dispatch=self.dispatch)
+ _dispatch=self.dispatch,
+ _dialect=self._dialect)
def _create_connection(self):
return self._conn
@@ -932,7 +955,8 @@ class AssertionPool(Pool):
self.logger.info("Pool recreating")
return self.__class__(self._creator, echo=self.echo,
logging_name=self._orig_logging_name,
- _dispatch=self.dispatch)
+ _dispatch=self.dispatch,
+ _dialect=self._dialect)
def _do_get(self):
if self._checked_out: