return getattr(self.__connection, 'is_valid', False)
+ @property
+ def _still_open_and_connection_is_valid(self):
+ return \
+ not self.closed and \
+ not self.invalidated and \
+ getattr(self.__connection, 'is_valid', False)
+
@property
def info(self):
"""A collection of per-DB-API connection instance properties."""
raise
def _rollback_impl(self):
- if not self.closed and not self.invalidated and \
- self._connection_is_valid:
+ if self._still_open_and_connection_is_valid:
if self._echo:
self.engine.logger.info("ROLLBACK")
try:
return name
def _rollback_to_savepoint_impl(self, name, context):
- if self._connection_is_valid:
+ if self._still_open_and_connection_is_valid:
self.engine.dialect.do_rollback_to_savepoint(self, name)
self.__transaction = context
def _release_savepoint_impl(self, name, context):
- if self._connection_is_valid:
+ if self._still_open_and_connection_is_valid:
self.engine.dialect.do_release_savepoint(self, name)
self.__transaction = context
def _begin_twophase_impl(self, xid):
- if self._connection_is_valid:
+ if self._still_open_and_connection_is_valid:
self.engine.dialect.do_begin_twophase(self, xid)
def _prepare_twophase_impl(self, xid):
- if self._connection_is_valid:
+ if self._still_open_and_connection_is_valid:
assert isinstance(self.__transaction, TwoPhaseTransaction)
self.engine.dialect.do_prepare_twophase(self, xid)
def _rollback_twophase_impl(self, xid, is_prepared):
- if self._connection_is_valid:
+ if self._still_open_and_connection_is_valid:
assert isinstance(self.__transaction, TwoPhaseTransaction)
self.engine.dialect.do_rollback_twophase(self, xid, is_prepared)
self.__transaction = None
def _commit_twophase_impl(self, xid, is_prepared):
- if self._connection_is_valid:
+ if self._still_open_and_connection_is_valid:
assert isinstance(self.__transaction, TwoPhaseTransaction)
self.engine.dialect.do_commit_twophase(self, xid, is_prepared)
self.__transaction = None
context.handle_dbapi_exception(e)
is_disconnect = self.dialect.is_disconnect(e)
+
if is_disconnect:
self.invalidate(e)
self.engine.dispose()
conn.close()
+ def test_rollback_on_invalid_plain(self):
+ conn = engine.connect()
+ trans = conn.begin()
+ conn.invalidate()
+ trans.rollback()
+
+ @testing.requires.two_phase_transactions
+ def test_rollback_on_invalid_twophase(self):
+ conn = engine.connect()
+ trans = conn.begin_twophase()
+ conn.invalidate()
+ trans.rollback()
+
+ @testing.requires.savepoints
+ def test_rollback_on_invalid_savepoint(self):
+ conn = engine.connect()
+ trans = conn.begin()
+ trans2 = conn.begin_nested()
+ conn.invalidate()
+ trans2.rollback()
+
def test_invalidate_twice(self):
conn = engine.connect()
conn.invalidate()