try: from functools import wraps except ImportError: from django.utils.functional import wraps # Python 2.3, 2.4 fallback. from django.db import transaction def commit_on_success_unless_managed(func): """ If the decorated function runs successfully, a commit is made, unless the transactions are being managed; if the function produces an exception, a rollback is made, again unless transactions are being managed somewhere else. """ def _commit_on_success_unless_managed(*args, **kw): try: if transaction.is_managed(): forced_managed = False else: transaction.enter_transaction_management() forced_managed = True try: res = func(*args, **kw) except: # All exceptions must be handled here (even string ones). if transaction.is_dirty(): if forced_managed: transaction.rollback() else: transaction.rollback_unless_managed() raise else: if transaction.is_dirty(): if forced_managed: transaction.commit() else: transaction.commit_unless_managed() return res finally: if forced_managed: transaction.leave_transaction_management() return wraps(func)(_commit_on_success_unless_managed)