Django

Code

Ticket #6623: commit_manually_exception_pass_thru2.diff

File commit_manually_exception_pass_thru2.diff, 2.6 kB (added by justine <jtunney@lobstertech.com>, 3 months ago)
  • django/db/transaction.py

    old new  
    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)