Commits

J.A. Roberts Tunney  committed aea577e

minor bug fix to commit manually decorator which after two years i think is finally in django 1.2

  • Participants
  • Parent commits 763983d
  • Branches 1.0.2

Comments (0)

Files changed (1)

File django/db/transaction.py

     if thread_ident not in dirty:
         dirty[thread_ident] = False
 
-def leave_transaction_management():
+def leave_transaction_management(exception=None):
     """
     Leaves transaction management for a running thread. A dirty flag is carried
     over to the surrounding block, as a commit will commit all changes, even
     those from outside. (Commits are on connection level.)
+
+    If this function is called from within a finally block where an
+    exception is in the process of working its way up the stack, pass
+    the exception argument so we don't raise a new exception over the
+    pending one.
     """
     thread_ident = thread.get_ident()
     if thread_ident in state and state[thread_ident]:
         raise TransactionManagementError("This code isn't under transaction management")
     if dirty.get(thread_ident, False):
         rollback()
-        raise TransactionManagementError("Transaction managed block ended with pending COMMIT/ROLLBACK")
+        if not exception:
+            raise TransactionManagementError("Transaction managed block ended with pending COMMIT/ROLLBACK")
     dirty[thread_ident] = False
 
 def is_dirty():
     control in web apps.
     """
     def _commit_on_success(*args, **kw):
+        exc = None
         try:
             enter_transaction_management()
             managed(True)
             try:
                 res = func(*args, **kw)
-            except:
+            except Exception, exc:
                 # All exceptions must be handled here (even string ones).
                 if is_dirty():
                     rollback()
                     commit()
             return res
         finally:
-            leave_transaction_management()
+            leave_transaction_management(exc)
     return wraps(func)(_commit_on_success)
 
 def commit_manually(func):
     themselves.
     """
     def _commit_manually(*args, **kw):
+        exc = None
         try:
-            enter_transaction_management()
-            managed(True)
-            return func(*args, **kw)
+            try:
+                enter_transaction_management()
+                managed(True)
+                return func(*args, **kw)
+            except Exception, exc:
+                raise
         finally:
-            leave_transaction_management()
+            leave_transaction_management(exc)
 
     return wraps(func)(_commit_manually)