Ticket #9964: 9964-against-10052.patch

File 9964-against-10052.patch, 27.7 KB (added by shai, 6 years ago)

not-yet-ready patch for comments

  • django/db/transaction/fast_select.py

     
    1010
    1111Managed transactions don't do those commits, but will need some kind of manual
    1212or implicit commits or rollbacks.
     13
     14This is a version of the transaction manager which marks transactions
     15as 'clean' or 'dirty', and neglects to close 'clean' transactions to
     16improve performnce.
     17
     18TODO: Explain when this breaks, and when it is less efficient
    1319"""
    1420
     21
    1522try:
    1623    import thread
    1724except ImportError:
    1825    import dummy_thread as thread
    19 try:
    20     from functools import wraps
    21 except ImportError:
    22     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     26
    2327from django.db import connection
    2428from django.conf import settings
    2529
    26 class TransactionManagementError(Exception):
    27     """
    28     This exception is thrown when something bad happens with transaction
    29     management.
    30     """
    31     pass
     30from django.db.transaction import TransactionManagementError
     31from django.db.transaction import state, savepoint_state
     32from django.db.transaction import is_managed, clean_savepoints, rollback()
    3233
    33 # The states are dictionaries of lists. The key to the dict is the current
    34 # thread and the list is handled as a stack of values.
    35 state = {}
    36 savepoint_state = {}
    37 
    3834# The dirty flag is set by *_unless_managed functions to denote that the
    3935# code under transaction management has changed things to require a
    4036# database commit.
     
    109105        raise TransactionManagementError("This code isn't under transaction management")
    110106    clean_savepoints()
    111107
    112 def clean_savepoints():
    113     thread_ident = thread.get_ident()
    114     if thread_ident in savepoint_state:
    115         del savepoint_state[thread_ident]
    116 
    117 def is_managed():
    118     """
    119     Checks whether the transaction manager is in manual or in auto state.
    120     """
    121     thread_ident = thread.get_ident()
    122     if thread_ident in state:
    123         if state[thread_ident]:
    124             return state[thread_ident][-1]
    125     return settings.TRANSACTIONS_MANAGED
    126 
    127 def managed(flag=True):
    128     """
    129     Puts the transaction manager into a manual state: managed transactions have
    130     to be committed explicitly by the user. If you switch off transaction
    131     management and there is a pending commit/rollback, the data will be
    132     commited.
    133     """
    134     thread_ident = thread.get_ident()
    135     top = state.get(thread_ident, None)
    136     if top:
    137         top[-1] = flag
    138         if not flag and is_dirty():
    139             connection._commit()
    140             set_clean()
    141     else:
    142         raise TransactionManagementError("This code isn't under transaction management")
    143 
    144 def commit_unless_managed():
    145     """
    146     Commits changes if the system is not in managed transaction mode.
    147     """
    148     if not is_managed():
    149         connection._commit()
    150         clean_savepoints()
    151     else:
    152         set_dirty()
    153 
    154 def rollback_unless_managed():
    155     """
    156     Rolls back changes if the system is not in managed transaction mode.
    157     """
    158     if not is_managed():
    159         connection._rollback()
    160     else:
    161         set_dirty()
    162 
    163 def commit():
    164     """
    165     Does the commit itself and resets the dirty flag.
    166     """
    167     connection._commit()
    168     set_clean()
    169 
    170 def rollback():
    171     """
    172     This function does the rollback itself and resets the dirty flag.
    173     """
    174     connection._rollback()
    175     set_clean()
    176 
    177 def savepoint():
    178     """
    179     Creates a savepoint (if supported and required by the backend) inside the
    180     current transaction. Returns an identifier for the savepoint that will be
    181     used for the subsequent rollback or commit.
    182     """
    183     thread_ident = thread.get_ident()
    184     if thread_ident in savepoint_state:
    185         savepoint_state[thread_ident].append(None)
    186     else:
    187         savepoint_state[thread_ident] = [None]
    188     tid = str(thread_ident).replace('-', '')
    189     sid = "s%s_x%d" % (tid, len(savepoint_state[thread_ident]))
    190     connection._savepoint(sid)
    191     return sid
    192 
    193 def savepoint_rollback(sid):
    194     """
    195     Rolls back the most recent savepoint (if one exists). Does nothing if
    196     savepoints are not supported.
    197     """
    198     if thread.get_ident() in savepoint_state:
    199         connection._savepoint_rollback(sid)
    200 
    201 def savepoint_commit(sid):
    202     """
    203     Commits the most recent savepoint (if one exists). Does nothing if
    204     savepoints are not supported.
    205     """
    206     if thread.get_ident() in savepoint_state:
    207         connection._savepoint_commit(sid)
    208 
    209 ##############
    210 # DECORATORS #
    211 ##############
    212 
    213 def autocommit(func):
    214     """
    215     Decorator that activates commit on save. This is Django's default behavior;
    216     this decorator is useful if you globally activated transaction management in
    217     your settings file and want the default behavior in some view functions.
    218     """
    219     def _autocommit(*args, **kw):
    220         try:
    221             enter_transaction_management(managed=False)
    222             managed(False)
    223             return func(*args, **kw)
    224         finally:
    225             leave_transaction_management()
    226     return wraps(func)(_autocommit)
    227 
    228 def commit_on_success(func):
    229     """
    230     This decorator activates commit on response. This way, if the view function
    231     runs successfully, a commit is made; if the viewfunc produces an exception,
    232     a rollback is made. This is one of the most common ways to do transaction
    233     control in web apps.
    234     """
    235     def _commit_on_success(*args, **kw):
    236         try:
    237             enter_transaction_management()
    238             managed(True)
    239             try:
    240                 res = func(*args, **kw)
    241             except:
    242                 # All exceptions must be handled here (even string ones).
    243                 if is_dirty():
    244                     rollback()
    245                 raise
    246             else:
    247                 if is_dirty():
    248                     commit()
    249             return res
    250         finally:
    251             leave_transaction_management()
    252     return wraps(func)(_commit_on_success)
    253 
    254 def commit_manually(func):
    255     """
    256     Decorator that activates manual transaction control. It just disables
    257     automatic transaction control and doesn't do any commit/rollback of its
    258     own -- it's up to the user to call the commit and rollback functions
    259     themselves.
    260     """
    261     def _commit_manually(*args, **kw):
    262         try:
    263             enter_transaction_management()
    264             managed(True)
    265             return func(*args, **kw)
    266         finally:
    267             leave_transaction_management()
    268 
    269     return wraps(func)(_commit_manually)
  • django/db/transaction/safe.py

     
     1"""
     2This module implements a transaction manager that can be used to define
     3transaction handling in a request or view function. It is used by transaction
     4control middleware and decorators.
     5
     6The transaction manager can be in managed or in auto state. Auto state means the
     7system is using a commit-on-save strategy (actually it's more like
     8commit-on-change). As soon as the .save() or .delete() (or related) methods are
     9called, a commit is made.
     10
     11Managed transactions don't do those commits, but will need some kind of manual
     12or implicit commits or rollbacks.
     13
     14This is a version of the transaction manager which treats all transactions
     15as 'dirty', so that they are always closed.
     16"""
     17
     18try:
     19    import thread
     20except ImportError:
     21    import dummy_thread as thread
     22try:
     23    from functools import wraps
     24except ImportError:
     25    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     26from django.db import connection
     27from django.conf import settings
     28
     29from django.db.transaction import TransactionManagementError
     30from django.db.transaction import state, savepoint_state
     31from django.db.transaction import is_managed, clean_savepoints, rollback
     32
     33
     34def enter_transaction_management(managed=True):
     35    """
     36    Enters transaction management for a running thread. It must be balanced with
     37    the appropriate leave_transaction_management call, since the actual state is
     38    managed as a stack.
     39
     40    The state and dirty flag are carried over from the surrounding block or
     41    from the settings, if there is no surrounding block (dirty is always false
     42    when no current block is running).
     43    """
     44    thread_ident = thread.get_ident()
     45    if thread_ident in state and state[thread_ident]:
     46        state[thread_ident].append(state[thread_ident][-1])
     47    else:
     48        state[thread_ident] = []
     49        state[thread_ident].append(settings.TRANSACTIONS_MANAGED)
     50    connection._enter_transaction_management(managed)
     51
     52def leave_transaction_management():
     53    """
     54    Leaves transaction management for a running thread.
     55    """
     56    connection._leave_transaction_management(is_managed())
     57    thread_ident = thread.get_ident()
     58    if thread_ident in state and state[thread_ident]:
     59        del state[thread_ident][-1]
     60    else:
     61        raise TransactionManagementError("This code isn't under transaction management")
     62    # Anything not committed should be rolled back
     63    # TODO: spurious database hits here? Just leave things be?
     64    rollback()
     65
     66def is_dirty():
     67    """
     68    All transactions are always dirty
     69    """
     70    return True
     71
     72def set_dirty():
     73    """
     74    All transactions are always dirty
     75    """
     76    pass
     77
     78def set_clean():
     79    """
     80    All transactions are always dirty
     81    """
     82    # TODO: Really? Retained from the fast_select version
     83    clean_savepoints()
     84
     85
     86
     87
  • django/db/transaction/__init__.py

     
     1"""
     2This module supports selection, by a setting, of a
     3transaction management "policy". Current policies
     4are "fast-select" (which leaves clean transactions
     5open) and "safe" (which makes sure all transactions
     6are closed, whether they are committed or rolled back.
     7
     8TODO: Document when fast is not safe, and when fast is
     9not even fast (repatable-read w/out MVCC).
     10"""
     11
     12###############
     13# Common base #
     14###############
     15
     16# These are common to the policies
     17try:
     18    import thread
     19except ImportError:
     20    import dummy_thread as thread
     21try:
     22    from functools import wraps
     23except ImportError:
     24    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     25from django.db import connection
     26from django.conf import settings
     27from django.core.exceptions import ImproperlyConfigured
     28
     29import fast_select
     30import safe
     31
     32class TransactionManagementError(Exception):
     33    """
     34    This exception is thrown when something bad happens with transaction
     35    management.
     36    """
     37    pass
     38
     39# The states are dictionaries of lists. The key to the dict is the current
     40# thread and the list is handled as a stack of values.
     41state = {}
     42savepoint_state = {}
     43
     44def is_managed():
     45    """
     46    Checks whether the transaction manager is in manual or in auto state.
     47    """
     48    thread_ident = thread.get_ident()
     49    if thread_ident in state:
     50        if state[thread_ident]:
     51            return state[thread_ident][-1]
     52    return settings.TRANSACTIONS_MANAGED
     53
     54def managed(flag=True):
     55    """
     56    Puts the transaction manager into a manual state: managed transactions have
     57    to be committed explicitly by the user. If you switch off transaction
     58    management and there is a pending commit/rollback, the data will be
     59    commited.
     60    """
     61    thread_ident = thread.get_ident()
     62    top = state.get(thread_ident, None)
     63    if top:
     64        top[-1] = flag
     65        if not flag and is_dirty():
     66            connection._commit()
     67            set_clean()
     68    else:
     69        raise TransactionManagementError("This code isn't under transaction management")
     70
     71def commit_unless_managed():
     72    """
     73    Commits changes if the system is not in managed transaction mode.
     74    """
     75    if not is_managed():
     76        connection._commit()
     77        clean_savepoints()
     78    else:
     79        set_dirty()
     80
     81def rollback_unless_managed():
     82    """
     83    Rolls back changes if the system is not in managed transaction mode.
     84    """
     85    if not is_managed():
     86        connection._rollback()
     87    else:
     88        set_dirty()
     89
     90def commit():
     91    """
     92    Does the commit itself and resets the dirty flag.
     93    """
     94    connection._commit()
     95    set_clean()
     96
     97def rollback():
     98    """
     99    This function does the rollback itself and resets the dirty flag.
     100    """
     101    connection._rollback()
     102    set_clean()
     103
     104def clean_savepoints():
     105    thread_ident = thread.get_ident()
     106    if thread_ident in savepoint_state:
     107        del savepoint_state[thread_ident]
     108
     109def savepoint():
     110    """
     111    Creates a savepoint (if supported and required by the backend) inside the
     112    current transaction. Returns an identifier for the savepoint that will be
     113    used for the subsequent rollback or commit.
     114    """
     115    thread_ident = thread.get_ident()
     116    if thread_ident in savepoint_state:
     117        savepoint_state[thread_ident].append(None)
     118    else:
     119        savepoint_state[thread_ident] = [None]
     120    tid = str(thread_ident).replace('-', '')
     121    sid = "s%s_x%d" % (tid, len(savepoint_state[thread_ident]))
     122    connection._savepoint(sid)
     123    return sid
     124
     125def savepoint_rollback(sid):
     126    """
     127    Rolls back the most recent savepoint (if one exists). Does nothing if
     128    savepoints are not supported.
     129    """
     130    if thread.get_ident() in savepoint_state:
     131        connection._savepoint_rollback(sid)
     132
     133def savepoint_commit(sid):
     134    """
     135    Commits the most recent savepoint (if one exists). Does nothing if
     136    savepoints are not supported.
     137    """
     138    if thread.get_ident() in savepoint_state:
     139        connection._savepoint_commit(sid)
     140
     141#####################
     142# Policy controlled #
     143#####################
     144
     145# Implementation note: we use a simple strategy of wrapping
     146# self-rewriting functions. Cost is an extra method call,
     147# which should be acceptable.
     148#
     149# Self-rewriting funcs: consider
     150#
     151# def f():
     152#   global f
     153#   f = some_other_func
     154#   return f()
     155#
     156# After the first call, any call to f goes directly to some_other_func --
     157# provided only that the name f is accessed via the module's global namespace.
     158# To ensure this, we add a slight variation: we use a self-rewriting _f,
     159# and f just calls _f (which it gets from module scope).
     160#
     161#TODO: This pattern can be factored out in several ways.
     162
     163def _get_policy_module():
     164    policy = getattr(settings, 'DATABASE_TRANSACTION_POLICY', 'fast_select')
     165    if policy=='fast_select':
     166        return fast_select
     167    elif policy=='safe':
     168        return safe
     169    else:
     170        raise ImproperlyConfigured, "Unknown transaction policy '%s'" % str(policy)
     171
     172def enter_transaction_management(managed=True):
     173    return _enter_transaction_management(managed)
     174def _enter_transaction_management(managed=True):
     175    global _enter_transaction_management
     176    _enter_transaction_management = _get_policy_module().enter_transaction_management
     177    return _enter_transaction_management(managed)
     178
     179def leave_transaction_management():
     180    return _leave_transaction_management()
     181def _leave_transaction_management():
     182    global _leave_transaction_management
     183    _leave_transaction_management = _get_policy_module().leave_transaction_management
     184    return _leave_transaction_management()
     185
     186def is_dirty():
     187    return _is_dirty()
     188def _is_dirty():
     189    global _is_dirty
     190    _is_dirty = _get_policy_module().is_dirty
     191    return _is_dirty()
     192
     193def set_dirty():
     194    return _set_dirty()
     195def _set_dirty():
     196    global _set_dirty
     197    _set_dirty = _get_policy_module().set_dirty
     198    return _set_dirty()
     199
     200def set_clean():
     201    return _set_clean()
     202def _set_clean():
     203    global _set_clean
     204    _set_clean = _get_policy_module().set_clean
     205    return _set_clean()
     206
     207##############
     208# DECORATORS #
     209##############
     210
     211# Decorators use the above functions, and their own code
     212# doesn't need to change to reflect policy; they are
     213# defined here to make sure they reference the right versions
     214# of the functions they use
     215
     216def autocommit(func):
     217    """
     218    Decorator that activates commit on save. This is Django's default behavior;
     219    this decorator is useful if you globally activated transaction management in
     220    your settings file and want the default behavior in some view functions.
     221    """
     222    def _autocommit(*args, **kw):
     223        try:
     224            enter_transaction_management(managed=False)
     225            managed(False)
     226            return func(*args, **kw)
     227        finally:
     228            leave_transaction_management()
     229    return wraps(func)(_autocommit)
     230
     231def commit_on_success(func):
     232    """
     233    This decorator activates commit on response. This way, if the view function
     234    runs successfully, a commit is made; if the viewfunc produces an exception,
     235    a rollback is made. This is one of the most common ways to do transaction
     236    control in web apps.
     237    """
     238    def _commit_on_success(*args, **kw):
     239        try:
     240            enter_transaction_management()
     241            managed(True)
     242            try:
     243                res = func(*args, **kw)
     244            except:
     245                # All exceptions must be handled here (even string ones).
     246                if is_dirty():
     247                    rollback()
     248                raise
     249            else:
     250                if is_dirty():
     251                    commit()
     252            return res
     253        finally:
     254            leave_transaction_management()
     255    return wraps(func)(_commit_on_success)
     256
     257def commit_manually(func):
     258    """
     259    Decorator that activates manual transaction control. It just disables
     260    automatic transaction control and doesn't do any commit/rollback of its
     261    own -- it's up to the user to call the commit and rollback functions
     262    themselves.
     263    """
     264    def _commit_manually(*args, **kw):
     265        try:
     266            enter_transaction_management()
     267            managed(True)
     268            return func(*args, **kw)
     269        finally:
     270            leave_transaction_management()
     271
     272    return wraps(func)(_commit_manually)
  • django/db/transaction.py

     
    1 """
    2 This module implements a transaction manager that can be used to define
    3 transaction handling in a request or view function. It is used by transaction
    4 control middleware and decorators.
    5 
    6 The transaction manager can be in managed or in auto state. Auto state means the
    7 system is using a commit-on-save strategy (actually it's more like
    8 commit-on-change). As soon as the .save() or .delete() (or related) methods are
    9 called, a commit is made.
    10 
    11 Managed transactions don't do those commits, but will need some kind of manual
    12 or implicit commits or rollbacks.
    13 """
    14 
    15 try:
    16     import thread
    17 except ImportError:
    18     import dummy_thread as thread
    19 try:
    20     from functools import wraps
    21 except ImportError:
    22     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
    23 from django.db import connection
    24 from django.conf import settings
    25 
    26 class TransactionManagementError(Exception):
    27     """
    28     This exception is thrown when something bad happens with transaction
    29     management.
    30     """
    31     pass
    32 
    33 # The states are dictionaries of lists. The key to the dict is the current
    34 # thread and the list is handled as a stack of values.
    35 state = {}
    36 savepoint_state = {}
    37 
    38 # The dirty flag is set by *_unless_managed functions to denote that the
    39 # code under transaction management has changed things to require a
    40 # database commit.
    41 dirty = {}
    42 
    43 def enter_transaction_management(managed=True):
    44     """
    45     Enters transaction management for a running thread. It must be balanced with
    46     the appropriate leave_transaction_management call, since the actual state is
    47     managed as a stack.
    48 
    49     The state and dirty flag are carried over from the surrounding block or
    50     from the settings, if there is no surrounding block (dirty is always false
    51     when no current block is running).
    52     """
    53     thread_ident = thread.get_ident()
    54     if thread_ident in state and state[thread_ident]:
    55         state[thread_ident].append(state[thread_ident][-1])
    56     else:
    57         state[thread_ident] = []
    58         state[thread_ident].append(settings.TRANSACTIONS_MANAGED)
    59     if thread_ident not in dirty:
    60         dirty[thread_ident] = False
    61     connection._enter_transaction_management(managed)
    62 
    63 def leave_transaction_management():
    64     """
    65     Leaves transaction management for a running thread. A dirty flag is carried
    66     over to the surrounding block, as a commit will commit all changes, even
    67     those from outside. (Commits are on connection level.)
    68     """
    69     connection._leave_transaction_management(is_managed())
    70     thread_ident = thread.get_ident()
    71     if thread_ident in state and state[thread_ident]:
    72         del state[thread_ident][-1]
    73     else:
    74         raise TransactionManagementError("This code isn't under transaction management")
    75     if dirty.get(thread_ident, False):
    76         rollback()
    77         raise TransactionManagementError("Transaction managed block ended with pending COMMIT/ROLLBACK")
    78     dirty[thread_ident] = False
    79 
    80 def is_dirty():
    81     """
    82     Returns True if the current transaction requires a commit for changes to
    83     happen.
    84     """
    85     return dirty.get(thread.get_ident(), False)
    86 
    87 def set_dirty():
    88     """
    89     Sets a dirty flag for the current thread and code streak. This can be used
    90     to decide in a managed block of code to decide whether there are open
    91     changes waiting for commit.
    92     """
    93     thread_ident = thread.get_ident()
    94     if thread_ident in dirty:
    95         dirty[thread_ident] = True
    96     else:
    97         raise TransactionManagementError("This code isn't under transaction management")
    98 
    99 def set_clean():
    100     """
    101     Resets a dirty flag for the current thread and code streak. This can be used
    102     to decide in a managed block of code to decide whether a commit or rollback
    103     should happen.
    104     """
    105     thread_ident = thread.get_ident()
    106     if thread_ident in dirty:
    107         dirty[thread_ident] = False
    108     else:
    109         raise TransactionManagementError("This code isn't under transaction management")
    110     clean_savepoints()
    111 
    112 def clean_savepoints():
    113     thread_ident = thread.get_ident()
    114     if thread_ident in savepoint_state:
    115         del savepoint_state[thread_ident]
    116 
    117 def is_managed():
    118     """
    119     Checks whether the transaction manager is in manual or in auto state.
    120     """
    121     thread_ident = thread.get_ident()
    122     if thread_ident in state:
    123         if state[thread_ident]:
    124             return state[thread_ident][-1]
    125     return settings.TRANSACTIONS_MANAGED
    126 
    127 def managed(flag=True):
    128     """
    129     Puts the transaction manager into a manual state: managed transactions have
    130     to be committed explicitly by the user. If you switch off transaction
    131     management and there is a pending commit/rollback, the data will be
    132     commited.
    133     """
    134     thread_ident = thread.get_ident()
    135     top = state.get(thread_ident, None)
    136     if top:
    137         top[-1] = flag
    138         if not flag and is_dirty():
    139             connection._commit()
    140             set_clean()
    141     else:
    142         raise TransactionManagementError("This code isn't under transaction management")
    143 
    144 def commit_unless_managed():
    145     """
    146     Commits changes if the system is not in managed transaction mode.
    147     """
    148     if not is_managed():
    149         connection._commit()
    150         clean_savepoints()
    151     else:
    152         set_dirty()
    153 
    154 def rollback_unless_managed():
    155     """
    156     Rolls back changes if the system is not in managed transaction mode.
    157     """
    158     if not is_managed():
    159         connection._rollback()
    160     else:
    161         set_dirty()
    162 
    163 def commit():
    164     """
    165     Does the commit itself and resets the dirty flag.
    166     """
    167     connection._commit()
    168     set_clean()
    169 
    170 def rollback():
    171     """
    172     This function does the rollback itself and resets the dirty flag.
    173     """
    174     connection._rollback()
    175     set_clean()
    176 
    177 def savepoint():
    178     """
    179     Creates a savepoint (if supported and required by the backend) inside the
    180     current transaction. Returns an identifier for the savepoint that will be
    181     used for the subsequent rollback or commit.
    182     """
    183     thread_ident = thread.get_ident()
    184     if thread_ident in savepoint_state:
    185         savepoint_state[thread_ident].append(None)
    186     else:
    187         savepoint_state[thread_ident] = [None]
    188     tid = str(thread_ident).replace('-', '')
    189     sid = "s%s_x%d" % (tid, len(savepoint_state[thread_ident]))
    190     connection._savepoint(sid)
    191     return sid
    192 
    193 def savepoint_rollback(sid):
    194     """
    195     Rolls back the most recent savepoint (if one exists). Does nothing if
    196     savepoints are not supported.
    197     """
    198     if thread.get_ident() in savepoint_state:
    199         connection._savepoint_rollback(sid)
    200 
    201 def savepoint_commit(sid):
    202     """
    203     Commits the most recent savepoint (if one exists). Does nothing if
    204     savepoints are not supported.
    205     """
    206     if thread.get_ident() in savepoint_state:
    207         connection._savepoint_commit(sid)
    208 
    209 ##############
    210 # DECORATORS #
    211 ##############
    212 
    213 def autocommit(func):
    214     """
    215     Decorator that activates commit on save. This is Django's default behavior;
    216     this decorator is useful if you globally activated transaction management in
    217     your settings file and want the default behavior in some view functions.
    218     """
    219     def _autocommit(*args, **kw):
    220         try:
    221             enter_transaction_management(managed=False)
    222             managed(False)
    223             return func(*args, **kw)
    224         finally:
    225             leave_transaction_management()
    226     return wraps(func)(_autocommit)
    227 
    228 def commit_on_success(func):
    229     """
    230     This decorator activates commit on response. This way, if the view function
    231     runs successfully, a commit is made; if the viewfunc produces an exception,
    232     a rollback is made. This is one of the most common ways to do transaction
    233     control in web apps.
    234     """
    235     def _commit_on_success(*args, **kw):
    236         try:
    237             enter_transaction_management()
    238             managed(True)
    239             try:
    240                 res = func(*args, **kw)
    241             except:
    242                 # All exceptions must be handled here (even string ones).
    243                 if is_dirty():
    244                     rollback()
    245                 raise
    246             else:
    247                 if is_dirty():
    248                     commit()
    249             return res
    250         finally:
    251             leave_transaction_management()
    252     return wraps(func)(_commit_on_success)
    253 
    254 def commit_manually(func):
    255     """
    256     Decorator that activates manual transaction control. It just disables
    257     automatic transaction control and doesn't do any commit/rollback of its
    258     own -- it's up to the user to call the commit and rollback functions
    259     themselves.
    260     """
    261     def _commit_manually(*args, **kw):
    262         try:
    263             enter_transaction_management()
    264             managed(True)
    265             return func(*args, **kw)
    266         finally:
    267             leave_transaction_management()
    268 
    269     return wraps(func)(_commit_manually)
  • django/conf/project_template/settings.py

     
    1616DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
    1717DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
    1818
     19
     20DATABASE_TRANSACTION_POLICY = 'safe' # Options: 'safe','fast_select'; TODO: better doc.
     21
    1922# Local time zone for this installation. Choices can be found here:
    2023# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
    2124# although not all choices may be available on all operating systems.
Back to Top