Index: django/db/transaction.py
===================================================================
--- django/db/transaction.py	(revision 8437)
+++ django/db/transaction.py	(working copy)
@@ -59,11 +59,16 @@
     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]:
@@ -72,7 +77,8 @@
         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():
@@ -231,12 +237,13 @@
     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()
@@ -246,7 +253,7 @@
                     commit()
             return res
         finally:
-            leave_transaction_management()
+            leave_transaction_management(exc)
     return wraps(func)(_commit_on_success)
 
 def commit_manually(func):
@@ -257,11 +264,15 @@
     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)
