Ticket #6623: commit_manually_exception_pass_thru2.diff

File commit_manually_exception_pass_thru2.diff, 2.6 KB (added by justine <jtunney@…>, 7 years ago)
  • django/db/transaction.py

     
    5959    if thread_ident not in dirty:
    6060        dirty[thread_ident] = False
    6161
    62 def leave_transaction_management():
     62def leave_transaction_management(exception=None):
    6363    """
    6464    Leaves transaction management for a running thread. A dirty flag is carried
    6565    over to the surrounding block, as a commit will commit all changes, even
    6666    those from outside. (Commits are on connection level.)
     67
     68    If this function is called from within a finally block where an
     69    exception is in the process of working its way up the stack, pass
     70    the exception argument so we don't raise a new exception over the
     71    pending one.
    6772    """
    6873    thread_ident = thread.get_ident()
    6974    if thread_ident in state and state[thread_ident]:
     
    7277        raise TransactionManagementError("This code isn't under transaction management")
    7378    if dirty.get(thread_ident, False):
    7479        rollback()
    75         raise TransactionManagementError("Transaction managed block ended with pending COMMIT/ROLLBACK")
     80        if not exception:
     81            raise TransactionManagementError("Transaction managed block ended with pending COMMIT/ROLLBACK")
    7682    dirty[thread_ident] = False
    7783
    7884def is_dirty():
     
    231237    control in web apps.
    232238    """
    233239    def _commit_on_success(*args, **kw):
     240        exc = None
    234241        try:
    235242            enter_transaction_management()
    236243            managed(True)
    237244            try:
    238245                res = func(*args, **kw)
    239             except:
     246            except Exception, exc:
    240247                # All exceptions must be handled here (even string ones).
    241248                if is_dirty():
    242249                    rollback()
     
    246253                    commit()
    247254            return res
    248255        finally:
    249             leave_transaction_management()
     256            leave_transaction_management(exc)
    250257    return wraps(func)(_commit_on_success)
    251258
    252259def commit_manually(func):
     
    257264    themselves.
    258265    """
    259266    def _commit_manually(*args, **kw):
     267        exc = None
    260268        try:
    261             enter_transaction_management()
    262             managed(True)
    263             return func(*args, **kw)
     269            try:
     270                enter_transaction_management()
     271                managed(True)
     272                return func(*args, **kw)
     273            except Exception, exc:
     274                raise
    264275        finally:
    265             leave_transaction_management()
     276            leave_transaction_management(exc)
    266277
    267278    return wraps(func)(_commit_manually)
Back to Top