AttributeError: 'Connection' object has no attribute '_Connection__connection' when mysql server is restarted & Session.close() is performed
Issue #2317
resolved
Python 2.7.2 Sqlalchemy 0.7.3
When I start my app, then restart mysql server, I receive this upon Session.commit() (same for Session.rollback(), Session.close() when catching SQLAlchemyError)
Most of the traceback is here:
self = <sqlalchemy.orm.session.Session object at 0x2436a10>
644
---> 645 self.transaction.commit()
646
File "pyenv/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py", line 313, in SessionTransaction.commit
self = <sqlalchemy.orm.session.SessionTransaction object at 0x2436b50>
312 if not self._prepared:
---> 313 self._prepare_impl()
314
File "pyenv/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py", line 304, in SessionTransaction._prepare_impl
self = <sqlalchemy.orm.session.SessionTransaction object at 0x2436b50>
303 except:
---> 304 self.rollback()
stx = <ref offset=-1 name=self>
t = (
<sqlalchemy.engine.base.Connection object at 0x23543d0>,
<sqlalchemy.engine.base.TwoPhaseTransaction object at 0x2354c10>,
True,
)
305 raise
File "pyenv/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py", line 338, in SessionTransaction.rollback
self = <sqlalchemy.orm.session.SessionTransaction object at 0x2436b50>
_capture_exception = False
337 if transaction._parent is None or transaction.nested:
---> 338 transaction._rollback_impl()
stx = <ref offset=-2 name=self>
transaction = <ref offset=-2 name=self>
339 transaction._deactivate()
File "pyenv/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py", line 356, in SessionTransaction._rollback_impl
self = <sqlalchemy.orm.session.SessionTransaction object at 0x2436b50>
355 for t in set(self._connections.values()):
---> 356 t[1](1).rollback()
t = <ref offset=-2>
357
File "pyenv/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1960, in Transaction.rollback
self = <sqlalchemy.engine.base.TwoPhaseTransaction object at 0x2354c10>
1959 return
--> 1960 self._do_rollback()
1961 self.is_active = False
File "pyenv/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py", line 2056, in TwoPhaseTransaction._do_rollback
self = <sqlalchemy.engine.base.TwoPhaseTransaction object at 0x2354c10>
2055 def _do_rollback(self):
--> 2056 self.connection._rollback_twophase_impl(self.xid, self._is_prepared)
2057
File "pyenv/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1279, in Connection._rollback_twophase_impl
self = <sqlalchemy.engine.base.Connection object at 0x23543d0>
xid = '_sa_3756cd31c58d286a70a2b4e149749534'
is_prepared = False
1278
--> 1279 if self._connection_is_valid:
1280 assert isinstance(self.__transaction, TwoPhaseTransaction)
File "pyenv/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1031, in Connection._connection_is_valid
self = <sqlalchemy.engine.base.Connection object at 0x23543d0>
1030
--> 1031 return getattr(self.__connection, 'is_valid', False)
1032
AttributeError: 'Connection' object has no attribute '_Connection__connection'
Comments (6)
-
repo owner -
Account Deleted Well, removing twophase=True resolves the problem. The setting was left over from times when we used more than one db.
I also applied 2317.patch and tested with twophase=True and this patch seems to solve this issue.
Thanks
-
repo owner thanks ! I need to implement tests on the SQLAlchemy side, then I can commit this.
-
repo owner - changed status to resolved
-
repo owner backported to 0.6 in a6535d17fb41ec5c6bfed07687d9c1e05ff5e91e
-
repo owner - removed milestone
Removing milestone: 0.7.4 (automated comment)
- Log in to comment
This is definitely a bug, though if I were developing this today the solution would be that you'd just get a much nicer exception about calling methods on an invalidated connection. However, the default transaction is apparently letting rollback/commit/whatever silently pass on an invalid connection, so for now that should be the behavior of the two phase transaction as well.
I'd skip the usage of "twophase=True" for now unless you are actually using it (very rare overall, triply so for MySQL).
tests: rollback(), commit(), invalidate(), close() on all three transaction types, for invalid connection, closed connection.