1
- from contextlib import ContextDecorator , contextmanager
1
+ from contextlib import ContextDecorator
2
2
3
3
from django .db import (
4
4
DEFAULT_DB_ALIAS ,
5
5
DatabaseError ,
6
6
Error ,
7
- ProgrammingError ,
8
- connections ,
9
7
)
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
78
9
79
10
80
11
def on_commit (func , using = None , robust = False ):
@@ -125,42 +56,38 @@ def __init__(self, using, durable):
125
56
def __enter__ (self ):
126
57
connection = get_connection (self .using )
127
58
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 :
133
60
raise RuntimeError (
134
61
"A durable atomic block cannot be nested within another atomic block."
135
62
)
136
- if not connection .in_atomic_block :
63
+ if not connection .in_atomic_block_mongo :
137
64
# 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 :
148
75
# We're already in a transaction
149
76
pass
150
77
else :
151
78
connection ._start_transaction (
152
79
False , force_begin_transaction_with_broken_autocommit = True
153
80
)
154
- connection .in_atomic_block = True
81
+ connection .in_atomic_block_mongo = True
155
82
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 )
158
85
159
86
def __exit__ (self , exc_type , exc_value , traceback ):
160
87
connection = get_connection (self .using )
161
88
162
- if connection .in_atomic_block :
163
- connection .atomic_blocks .pop ()
89
+ if connection .in_atomic_block_mongo :
90
+ connection .atomic_blocks_mongo .pop ()
164
91
165
92
# Prematurely unset this flag to allow using commit or rollback.
166
93
connection ._in_atomic_block = False
@@ -170,7 +97,7 @@ def __exit__(self, exc_type, exc_value, traceback):
170
97
# Wait until we exit the outermost block.
171
98
pass
172
99
173
- elif exc_type is None and not connection .needs_rollback :
100
+ elif exc_type is None and not connection .needs_rollback_mongo :
174
101
if connection ._in_atomic_block :
175
102
# Release savepoint if there is one
176
103
pass
@@ -189,10 +116,10 @@ def __exit__(self, exc_type, exc_value, traceback):
189
116
else :
190
117
# This flag will be set to True again if there isn't a savepoint
191
118
# 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 :
194
121
# Mark for rollback
195
- connection .needs_rollback = True
122
+ connection .needs_rollback_mongo = True
196
123
else :
197
124
# Roll back transaction
198
125
try :
@@ -203,7 +130,7 @@ def __exit__(self, exc_type, exc_value, traceback):
203
130
connection .close ()
204
131
finally :
205
132
# Outermost block exit when autocommit was enabled.
206
- if not connection .in_atomic_block :
133
+ if not connection .in_atomic_block_mongo :
207
134
if connection .closed_in_transaction :
208
135
connection .connection = None
209
136
# else:
@@ -213,7 +140,7 @@ def __exit__(self, exc_type, exc_value, traceback):
213
140
if connection .closed_in_transaction :
214
141
connection .connection = None
215
142
else :
216
- connection .in_atomic_block = False
143
+ connection .in_atomic_block_mongo = False
217
144
218
145
219
146
def atomic (using = None , durable = False ):
@@ -223,19 +150,3 @@ def atomic(using=None, durable=False):
223
150
return Atomic (DEFAULT_DB_ALIAS , durable )(using )
224
151
# Decorator: @atomic(...) or context manager: with atomic(...): ...
225
152
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