diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-11-22 23:45:24 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-11-22 23:45:24 -0500 |
| commit | 0f0ce7c9b7c4b3a9f1329dfa9c42d0d69386d48f (patch) | |
| tree | d50620cff987eeb763c96bb24b7c62558dab95a7 /lib/sqlalchemy/pool.py | |
| parent | 0c9eb439267fc48e38a1390acf0eaa34d939867a (diff) | |
| download | sqlalchemy-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.py | 76 |
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: |
