1- from contextlib import ContextDecorator , contextmanager
1+ from contextlib import ContextDecorator
22
33from django .db import (
44 DEFAULT_DB_ALIAS ,
55 DatabaseError ,
66 Error ,
7- ProgrammingError ,
8- connections ,
97)
10-
11-
12- class TransactionManagementError (ProgrammingError ):
13- """Transaction management is used improperly."""
14-
15-
16- def get_connection (using = None ):
17- """
18- Get a database connection by name, or the default database connection
19- if no name is provided. This is a private API.
20- """
21- if using is None :
22- using = DEFAULT_DB_ALIAS
23- return connections [using ]
24-
25-
26- def commit (using = None ):
27- """Commit a transaction."""
28- get_connection (using ).commit ()
29-
30-
31- def rollback (using = None ):
32- """Roll back a transaction."""
33- get_connection (using ).rollback ()
34-
35-
36- def set_rollback (rollback , using = None ):
37- """
38- Set or unset the "needs rollback" flag -- for *advanced use* only.
39-
40- When `rollback` is `True`, trigger a rollback when exiting the innermost
41- enclosing atomic block that has `savepoint=True` (that's the default). Use
42- this to force a rollback without raising an exception.
43-
44- When `rollback` is `False`, prevent such a rollback. Use this only after
45- rolling back to a known-good state! Otherwise, you break the atomic block
46- and data corruption may occur.
47- """
48- return get_connection (using ).set_rollback (rollback )
49-
50-
51- @contextmanager
52- def mark_for_rollback_on_error (using = None ):
53- """
54- Internal low-level utility to mark a transaction as "needs rollback" when
55- an exception is raised while not enforcing the enclosed block to be in a
56- transaction. This is needed by Model.save() and friends to avoid starting a
57- transaction when in autocommit mode and a single query is executed.
58-
59- It's equivalent to:
60-
61- connection = get_connection(using)
62- if connection.get_autocommit():
63- yield
64- else:
65- with transaction.atomic(using=using, savepoint=False):
66- yield
67-
68- but it uses low-level utilities to avoid performance overhead.
69- """
70- try :
71- yield
72- except Exception as exc :
73- connection = get_connection (using )
74- if connection .in_atomic_block :
75- connection .needs_rollback = True
76- connection .rollback_exc = exc
77- raise
8+ from django .db .transaction import get_connection
789
7910
8011def on_commit (func , using = None , robust = False ):
@@ -125,42 +56,38 @@ def __init__(self, using, durable):
12556 def __enter__ (self ):
12657 connection = get_connection (self .using )
12758
128- if (
129- self .durable
130- and connection .atomic_blocks
131- and not connection .atomic_blocks [- 1 ]._from_testcase
132- ):
59+ if self .durable and connection .atomic_blocks_mongo :
13360 raise RuntimeError (
13461 "A durable atomic block cannot be nested within another atomic block."
13562 )
136- if not connection .in_atomic_block :
63+ if not connection .in_atomic_block_mongo :
13764 # Reset state when entering an outermost atomic block.
138- connection .commit_on_exit = True
139- connection .needs_rollback = False
140- if not connection .get_autocommit ():
141- # Pretend we're already in an atomic block to bypass the code
142- # that disables autocommit to enter a transaction, and make a
143- # note to deal with this case in __exit__.
144- connection .in_atomic_block = True
145- connection .commit_on_exit = False
146-
147- if connection .in_atomic_block :
65+ connection .commit_on_exit_mongo = True
66+ connection .needs_rollback_mongo = False
67+ # if not connection.get_autocommit():
68+ # Pretend we're already in an atomic block to bypass the code
69+ # that disables autocommit to enter a transaction, and make a
70+ # note to deal with this case in __exit__.
71+ connection .in_atomic_block_mongo = True
72+ connection .commit_on_exit = False
73+
74+ if connection .in_atomic_block_mongo :
14875 # We're already in a transaction
14976 pass
15077 else :
15178 connection ._start_transaction (
15279 False , force_begin_transaction_with_broken_autocommit = True
15380 )
154- connection .in_atomic_block = True
81+ connection .in_atomic_block_mongo = True
15582
156- if connection .in_atomic_block :
157- connection .atomic_blocks .append (self )
83+ if connection .in_atomic_block_mongo :
84+ connection .atomic_blocks_mongo .append (self )
15885
15986 def __exit__ (self , exc_type , exc_value , traceback ):
16087 connection = get_connection (self .using )
16188
162- if connection .in_atomic_block :
163- connection .atomic_blocks .pop ()
89+ if connection .in_atomic_block_mongo :
90+ connection .atomic_blocks_mongo .pop ()
16491
16592 # Prematurely unset this flag to allow using commit or rollback.
16693 connection ._in_atomic_block = False
@@ -170,7 +97,7 @@ def __exit__(self, exc_type, exc_value, traceback):
17097 # Wait until we exit the outermost block.
17198 pass
17299
173- elif exc_type is None and not connection .needs_rollback :
100+ elif exc_type is None and not connection .needs_rollback_mongo :
174101 if connection ._in_atomic_block :
175102 # Release savepoint if there is one
176103 pass
@@ -189,10 +116,10 @@ def __exit__(self, exc_type, exc_value, traceback):
189116 else :
190117 # This flag will be set to True again if there isn't a savepoint
191118 # allowing to perform the rollback at this level.
192- connection .needs_rollback = False
193- if connection .in_atomic_block :
119+ connection .needs_rollback_mongo = False
120+ if connection .in_atomic_block_mongo :
194121 # Mark for rollback
195- connection .needs_rollback = True
122+ connection .needs_rollback_mongo = True
196123 else :
197124 # Roll back transaction
198125 try :
@@ -203,7 +130,7 @@ def __exit__(self, exc_type, exc_value, traceback):
203130 connection .close ()
204131 finally :
205132 # Outermost block exit when autocommit was enabled.
206- if not connection .in_atomic_block :
133+ if not connection .in_atomic_block_mongo :
207134 if connection .closed_in_transaction :
208135 connection .connection = None
209136 # else:
@@ -213,7 +140,7 @@ def __exit__(self, exc_type, exc_value, traceback):
213140 if connection .closed_in_transaction :
214141 connection .connection = None
215142 else :
216- connection .in_atomic_block = False
143+ connection .in_atomic_block_mongo = False
217144
218145
219146def atomic (using = None , durable = False ):
@@ -223,19 +150,3 @@ def atomic(using=None, durable=False):
223150 return Atomic (DEFAULT_DB_ALIAS , durable )(using )
224151 # Decorator: @atomic(...) or context manager: with atomic(...): ...
225152 return Atomic (using , durable )
226-
227-
228- def _non_atomic_requests (view , using ):
229- try :
230- view ._non_atomic_requests .add (using )
231- except AttributeError :
232- view ._non_atomic_requests = {using }
233- return view
234-
235-
236- def non_atomic_requests (using = None ):
237- if callable (using ):
238- return _non_atomic_requests (using , DEFAULT_DB_ALIAS )
239- if using is None :
240- using = DEFAULT_DB_ALIAS
241- return lambda view : _non_atomic_requests (view , using )
0 commit comments