error when use two-phase transactions and pass connection to session.bind_mapper after session.commit()
Steps to reproduce[BR] 1) I create new two-phase session and bind with bind_mapper(mapper, connectionObject)[BR] 2) session.commit() throws exception[BR]
The problem was in commit function, when it decides to set _ _transaction to None, next piece of code tried to make rollback() and _ _transaction is not instance of TwoPhaseTransaction.[BR]
I've fixed it by ugly hack in sqlalchemy.engine.base
from sqlalchemy.engine.base import Transaction
def close(self):
if not self._parent.is_active or self.connection._Connection__transaction is None:
return
if self._parent is self:
self.rollback()
Transaction.close = close
When I use engine instead of connection all works
Comments (6)
-
repo owner -
Account Deleted Rollback is allowed in this transaction.[BR] I think problem is in sqlalchemy.engine.base.Transaction.close method[BR] [BR] 1. In session.py after two phase transaction committed {{{t1.commit() #session.py:382}}} in base.Connection {{{self.__transaction}}} became None (base.py:_commit_twophase_impl():790)[BR] 2. session.py call {{{self.close():#session.py:390}}}[BR] 3. In {{{Session.close() # session.py:426}}} will be called {{{transaction.close()}}}, because I use connection instead of engine and autoclose is False[BR] 4. For two phase transactions in close method {{{self._parent is self}}}, so called rollback[BR] 5. Rollback in {{{Connection._rollback_twophase_impl #base.py:780}}} require
But it set None in commit and transaction not started yet
-
repo owner if you could illustrate with a small sample script that reproduces the error, it would greatly increase the chances of this fix being committed today or tomorrow, otherwise I'll have to find time to reproduce the issue.
-
Account Deleted from sqlalchemy import create_engine, MetaData, Table from sqlalchemy.orm import sessionmaker, mapper import vr.config as config engine = create_engine("mysql://%(user)s:%(passwd)s@%(host)s/%(db)s" % config.db.COMMON, pool_size=20) meta = MetaData(engine) structure = Table("someTable", meta, autoload=True) class MyTable(object): """ Table class """ mapper(MyTable, structure) connection = engine.connect() session = sessionmaker(autoflush=True, autocommit=False, expire_on_commit=False, twophase=True)() session.bind_mapper(MyTable, connection) t = MyTable() session.add(t) session.prepare() session.commit()
-
repo owner fixed for 0.5 branch + 0.6 in a69a094db57ab1c6220930274a96457b0c353221 9a746845d0ce5bfd3216f0ae05627687b5116968
-
repo owner - removed milestone
Removing milestone: 0.5.7 (automated comment)
- Log in to comment
can you add some detail about the "error" ? is the rollback() somehow disallowed on the connection ? what backend ?