Code

Ticket #9964: 9964-against-10052.patch

File 9964-against-10052.patch, 27.7 KB (added by shai, 5 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.