transaction management is used improperly pass def getconnectionusingnone if using is none using defaultdbalias return connectionsusing def getautocommitusingnone set the autocommit status of the connection return getconnectionusing setautocommitautocommit def commitusingnone roll back a transaction getconnectionusing rollback def savepointusingnone return getconnectionusing savepoint def savepointrollbacksid usingnone getconnectionusing savepointrollbacksid def savepointcommitsid usingnone getconnectionusing savepointcommitsid def cleansavepointsusingnone getconnectionusing cleansavepoints def getrollbackusingnone set or unset the needs rollback flag for advanced use only when rollback is true trigger a rollback when exiting the innermost enclosing atomic block that has savepointtrue that s the default use this to force a rollback without raising an exception when rollback is false prevent such a rollback use this only after rolling back to a knowngood state otherwise you break the atomic block and data corruption may occur internal lowlevel utility to mark a transaction as needs rollback when an exception is raised while not enforcing the enclosed block to be in a transaction this is needed by model save and friends to avoid starting a transaction when in autocommit mode and a single query is executed it s equivalent to connection getconnectionusing if connection getautocommit yield else with transaction atomicusingusing savepointfalse yield but it uses lowlevel utilities to avoid performance overhead register func to be called when the current transaction is committed if the current transaction is rolled back func will not be called decorators context managers guarantee the atomic execution of a given block an instance can be used either as a decorator or as a context manager when it s used as a decorator call wraps the execution of the decorated function in the instance itself used as a context manager when it s used as a context manager enter creates a transaction or a savepoint depending on whether a transaction is already in progress and exit commits the transaction or releases the savepoint on normal exit and rolls back the transaction or to the savepoint on exceptions it s possible to disable the creation of savepoints if the goal is to ensure that some code runs within a transaction without creating overhead a stack of savepoints identifiers is maintained as an attribute of the connection none denotes the absence of a savepoint this allows reentrancy even if the same atomicwrapper is reused for example it s possible to define oa atomic other and use oa or with oa multiple times since database connections are threadlocal this is threadsafe an atomic block can be tagged as durable in this case raise a runtimeerror if it s nested within another atomic block this guarantees that database changes in a durable block are committed to the database when the block exists without error this is a private api reset state when entering an outermost atomic block pretend we re already in an atomic block to bypass the code that disables autocommit to enter a transaction and make a note to deal with this case in exit we re already in a transaction create a savepoint unless we were told not to or we re already waiting for a rollback the second condition avoids creating useless savepoints and prevents overwriting needsrollback until the rollback is performed prematurely unset this flag to allow using commit or rollback the database will perform a rollback by itself wait until we exit the outermost block release savepoint if there is one the savepoint won t be reused release it to minimize overhead for the database server if rolling back to a savepoint fails mark for rollback at a higher level and avoid shadowing the original exception commit transaction an error during rollback means that something went wrong with the connection drop it this flag will be set to true again if there isn t a savepoint allowing to perform the rollback at this level roll back to savepoint if there is one mark for rollback otherwise the savepoint won t be reused release it to minimize overhead for the database server if rolling back to a savepoint fails mark for rollback at a higher level and avoid shadowing the original exception roll back transaction an error during rollback means that something went wrong with the connection drop it outermost block exit when autocommit was enabled outermost block exit when autocommit was disabled bare decorator atomic although the first argument is called using it s actually the function being decorated decorator atomic or context manager with atomic transaction management is used improperly get a database connection by name or the default database connection if no name is provided this is a private api get the autocommit status of the connection set the autocommit status of the connection commit a transaction roll back a transaction create a savepoint if supported and required by the backend inside the current transaction return an identifier for the savepoint that will be used for the subsequent rollback or commit roll back the most recent savepoint if one exists do nothing if savepoints are not supported commit the most recent savepoint if one exists do nothing if savepoints are not supported reset the counter used to generate unique savepoint ids in this thread get the needs rollback flag for advanced use only set or unset the needs rollback flag for advanced use only when rollback is true trigger a rollback when exiting the innermost enclosing atomic block that has savepoint true that s the default use this to force a rollback without raising an exception when rollback is false prevent such a rollback use this only after rolling back to a known good state otherwise you break the atomic block and data corruption may occur internal low level utility to mark a transaction as needs rollback when an exception is raised while not enforcing the enclosed block to be in a transaction this is needed by model save and friends to avoid starting a transaction when in autocommit mode and a single query is executed it s equivalent to connection get_connection using if connection get_autocommit yield else with transaction atomic using using savepoint false yield but it uses low level utilities to avoid performance overhead register func to be called when the current transaction is committed if the current transaction is rolled back func will not be called decorators context managers guarantee the atomic execution of a given block an instance can be used either as a decorator or as a context manager when it s used as a decorator __call__ wraps the execution of the decorated function in the instance itself used as a context manager when it s used as a context manager __enter__ creates a transaction or a savepoint depending on whether a transaction is already in progress and __exit__ commits the transaction or releases the savepoint on normal exit and rolls back the transaction or to the savepoint on exceptions it s possible to disable the creation of savepoints if the goal is to ensure that some code runs within a transaction without creating overhead a stack of savepoints identifiers is maintained as an attribute of the connection none denotes the absence of a savepoint this allows reentrancy even if the same atomicwrapper is reused for example it s possible to define oa atomic other and use oa or with oa multiple times since database connections are thread local this is thread safe an atomic block can be tagged as durable in this case raise a runtimeerror if it s nested within another atomic block this guarantees that database changes in a durable block are committed to the database when the block exists without error this is a private api reset state when entering an outermost atomic block pretend we re already in an atomic block to bypass the code that disables autocommit to enter a transaction and make a note to deal with this case in __exit__ we re already in a transaction create a savepoint unless we were told not to or we re already waiting for a rollback the second condition avoids creating useless savepoints and prevents overwriting needs_rollback until the rollback is performed prematurely unset this flag to allow using commit or rollback the database will perform a rollback by itself wait until we exit the outermost block release savepoint if there is one the savepoint won t be reused release it to minimize overhead for the database server if rolling back to a savepoint fails mark for rollback at a higher level and avoid shadowing the original exception commit transaction an error during rollback means that something went wrong with the connection drop it this flag will be set to true again if there isn t a savepoint allowing to perform the rollback at this level roll back to savepoint if there is one mark for rollback otherwise the savepoint won t be reused release it to minimize overhead for the database server if rolling back to a savepoint fails mark for rollback at a higher level and avoid shadowing the original exception roll back transaction an error during rollback means that something went wrong with the connection drop it outermost block exit when autocommit was enabled outermost block exit when autocommit was disabled bare decorator atomic although the first argument is called using it s actually the function being decorated decorator atomic or context manager with atomic
from contextlib import ContextDecorator, contextmanager

from django.db import (
    DEFAULT_DB_ALIAS,
    DatabaseError,
    Error,
    ProgrammingError,
    connections,
)


class TransactionManagementError(ProgrammingError):
    

    pass


def get_connection(using=None):
    
    if using is None:
        using = DEFAULT_DB_ALIAS
    return connections[using]


def get_autocommit(using=None):
    
    return get_connection(using).get_autocommit()


def set_autocommit(autocommit, using=None):
    
    return get_connection(using).set_autocommit(autocommit)


def commit(using=None):
    
    get_connection(using).commit()


def rollback(using=None):
    
    get_connection(using).rollback()


def savepoint(using=None):
    
    return get_connection(using).savepoint()


def savepoint_rollback(sid, using=None):
    
    get_connection(using).savepoint_rollback(sid)


def savepoint_commit(sid, using=None):
    
    get_connection(using).savepoint_commit(sid)


def clean_savepoints(using=None):
    
    get_connection(using).clean_savepoints()


def get_rollback(using=None):
    
    return get_connection(using).get_rollback()


def set_rollback(rollback, using=None):
    
    return get_connection(using).set_rollback(rollback)


@contextmanager
def mark_for_rollback_on_error(using=None):
    
    try:
        yield
    except Exception as exc:
        connection = get_connection(using)
        if connection.in_atomic_block:
            connection.needs_rollback = True
            connection.rollback_exc = exc
        raise


def on_commit(func, using=None, robust=False):
    
    get_connection(using).on_commit(func, robust)







class Atomic(ContextDecorator):
    

    def __init__(self, using, savepoint, durable):
        self.using = using
        self.savepoint = savepoint
        self.durable = durable
        self._from_testcase = False

    def __enter__(self):
        connection = get_connection(self.using)

        if (
            self.durable
            and connection.atomic_blocks
            and not connection.atomic_blocks[-1]._from_testcase
        ):
            raise RuntimeError(
                "A durable atomic block cannot be nested within another "
                "atomic block."
            )
        if not connection.in_atomic_block:
            
            connection.commit_on_exit = True
            connection.needs_rollback = False
            if not connection.get_autocommit():
                
                
                
                connection.in_atomic_block = True
                connection.commit_on_exit = False

        if connection.in_atomic_block:
            
            
            
            
            if self.savepoint and not connection.needs_rollback:
                sid = connection.savepoint()
                connection.savepoint_ids.append(sid)
            else:
                connection.savepoint_ids.append(None)
        else:
            connection.set_autocommit(
                False, force_begin_transaction_with_broken_autocommit=True
            )
            connection.in_atomic_block = True

        if connection.in_atomic_block:
            connection.atomic_blocks.append(self)

    def __exit__(self, exc_type, exc_value, traceback):
        connection = get_connection(self.using)

        if connection.in_atomic_block:
            connection.atomic_blocks.pop()

        if connection.savepoint_ids:
            sid = connection.savepoint_ids.pop()
        else:
            
            connection.in_atomic_block = False

        try:
            if connection.closed_in_transaction:
                
                
                pass

            elif exc_type is None and not connection.needs_rollback:
                if connection.in_atomic_block:
                    
                    if sid is not None:
                        try:
                            connection.savepoint_commit(sid)
                        except DatabaseError:
                            try:
                                connection.savepoint_rollback(sid)
                                
                                
                                connection.savepoint_commit(sid)
                            except Error:
                                
                                
                                
                                connection.needs_rollback = True
                            raise
                else:
                    
                    try:
                        connection.commit()
                    except DatabaseError:
                        try:
                            connection.rollback()
                        except Error:
                            
                            
                            connection.close()
                        raise
            else:
                
                
                connection.needs_rollback = False
                if connection.in_atomic_block:
                    
                    
                    if sid is None:
                        connection.needs_rollback = True
                    else:
                        try:
                            connection.savepoint_rollback(sid)
                            
                            
                            connection.savepoint_commit(sid)
                        except Error:
                            
                            
                            
                            connection.needs_rollback = True
                else:
                    
                    try:
                        connection.rollback()
                    except Error:
                        
                        
                        connection.close()

        finally:
            
            if not connection.in_atomic_block:
                if connection.closed_in_transaction:
                    connection.connection = None
                else:
                    connection.set_autocommit(True)
            
            elif not connection.savepoint_ids and not connection.commit_on_exit:
                if connection.closed_in_transaction:
                    connection.connection = None
                else:
                    connection.in_atomic_block = False


def atomic(using=None, savepoint=True, durable=False):
    
    
    if callable(using):
        return Atomic(DEFAULT_DB_ALIAS, savepoint, durable)(using)
    
    else:
        return Atomic(using, savepoint, durable)


def _non_atomic_requests(view, using):
    try:
        view._non_atomic_requests.add(using)
    except AttributeError:
        view._non_atomic_requests = {using}
    return view


def non_atomic_requests(using=None):
    if callable(using):
        return _non_atomic_requests(using, DEFAULT_DB_ALIAS)
    else:
        if using is None:
            using = DEFAULT_DB_ALIAS
        return lambda view: _non_atomic_requests(view, using)