- changed title to session transaction is not deactivated when rollback fails
- edited description
session transaction is not deactivated when rollback fails
Issue #4050
resolved
due to #3934, affects downstream oslo.db test_cause_for_failed_flush_plus_no_savepoint
users, User = self.tables.users, self.classes.User
mapper(User, users)
session = Session(bind=testing.db)
rollback_error = testing.db.dialect.dbapi.InterfaceError(
"Can't roll back to savepoint")
def prevent_savepoint_rollback(
cursor, statement, parameters, context=None):
if "rollback to savepoint" in statement.lower():
raise rollback_error
self.event_listen(
testing.db.dialect,
"do_execute", prevent_savepoint_rollback)
with session.transaction:
session.add(User(id=1, name='x'))
session.begin_nested()
# raises IntegrityError on flush
session.add(User(id=1, name='x'))
assert_raises_message(
sa_exc.InterfaceError,
"Can't roll back to savepoint",
session.commit,
)
# rollback succeeds, because the Session is deactivated
eq_(session.transaction._state, _session.DEACTIVE)
session.rollback()
# back to normal
eq_(session.transaction._state, _session.ACTIVE)
trans = session.transaction
# leave the outermost trans
session.rollback()
# trans is now closed
eq_(trans._state, _session.CLOSED)
# outermost transction is new
is_not_(session.transaction, trans)
# outermost is active
eq_(session.transaction._state, _session.ACTIVE)
Comments (2)
-
reporter -
reporter - changed status to resolved
Deactivate transaction if rollback fails
Fixed regression introduced in 1.2.0b1 due to
3934
where the :class:.Session
would fail to "deactivate" the transaction, if a rollback failed (the target issue is when MySQL loses track of a SAVEPOINT). This would cause a subsequent call to :meth:.Session.rollback
to raise an error a second time, rather than completing and bringing the :class:.Session
back to ACTIVE.Fixes:
#4050Change-Id: Id245e8dd3487cb006b2d6631c8bd513b5ce81abe→ <<cset 8b53548b9e97>>
- Log in to comment