diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-11-19 15:45:17 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-11-19 15:45:17 -0500 |
commit | a6fe4dc0c8ebc346a90dd849a86dac9345d74515 (patch) | |
tree | e3411c2a3ede5e942d3a5ea65c635dfe7cd2e745 /lib/sqlalchemy/orm/session.py | |
parent | 1dc805dd4d902b9204703f0bd6151c58f1f287af (diff) | |
download | sqlalchemy-a6fe4dc0c8ebc346a90dd849a86dac9345d74515.tar.gz |
- A rare case which occurs when a :meth:`.Session.rollback` fails in the
scope of a :meth:`.Session.flush` operation that's raising an
exception, as has been observed in some MySQL SAVEPOINT cases, prevents
the original database exception from being observed when it was
emitted during flush, but only on Py2K because Py2K does not support
exception chaining; on Py3K the originating exception is chained. As
a workaround, a warning is emitted in this specific case showing at
least the string message of the original database error before we
proceed to raise the rollback-originating exception.
fixes #2696
Diffstat (limited to 'lib/sqlalchemy/orm/session.py')
-rw-r--r-- | lib/sqlalchemy/orm/session.py | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index c726443f6..4272d7d78 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -408,11 +408,23 @@ class SessionTransaction(object): for subtransaction in stx._iterate_parents(upto=self): subtransaction.close() + if _capture_exception: + captured_exception = sys.exc_info()[1] + boundary = self if self._state in (ACTIVE, PREPARED): for transaction in self._iterate_parents(): if transaction._parent is None or transaction.nested: - transaction._rollback_impl() + try: + transaction._rollback_impl() + except Exception: + if _capture_exception: + util.warn( + "An exception raised during a Session " + "persistence operation cannot be raised " + "due to an additional ROLLBACK exception; " + "the exception is: %s" % captured_exception) + raise transaction._state = DEACTIVE boundary = transaction break @@ -434,7 +446,7 @@ class SessionTransaction(object): self.close() if self._parent and _capture_exception: - self._parent._rollback_exception = sys.exc_info()[1] + self._parent._rollback_exception = captured_exception sess.dispatch.after_soft_rollback(sess, self) |