Skip to content

Commit 98f23f8

Browse files
committed
simplify
1 parent 60a5139 commit 98f23f8

File tree

6 files changed

+22
-65
lines changed

6 files changed

+22
-65
lines changed

django_mongodb_backend/base.py

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,11 @@ def _isnull_operator(a, b):
152152
def __init__(self, settings_dict, alias=DEFAULT_DB_ALIAS):
153153
super().__init__(settings_dict, alias=alias)
154154
self.session = None
155-
156-
# Transaction related attributes.
157-
# Tracks if the connection is in a transaction managed by 'atomic'.
155+
# Tracks if the connection is in a transaction managed by
156+
# django_mongodb_backend.transaction.atomic.
158157
self.in_atomic_block_mongo = False
159158
# Current number of nested 'atomic' calls.
160159
self.nested_atomics = 0
161-
# Stack of active 'atomic' blocks.
162-
self.atomic_blocks_mongo = []
163-
# Tracks if the transaction should be rolled back to the next
164-
# available savepoint because of an exception in an inner block.
165-
self.needs_rollback_mongo = False
166-
self.rollback_exc_mongo = None
167160

168161
def get_collection(self, name, **kwargs):
169162
collection = Collection(self.database, name, **kwargs)
@@ -254,13 +247,6 @@ def close_pool(self):
254247
def cursor(self):
255248
return Cursor()
256249

257-
def validate_no_broken_transaction(self):
258-
if self.needs_rollback_mongo:
259-
raise TransactionManagementError(
260-
"An error occurred in the current transaction. You can't "
261-
"execute queries until the end of the 'atomic' block."
262-
) from self.rollback_exc
263-
264250
def validate_no_atomic_block(self):
265251
"""Raise an error if an atomic block is active."""
266252
if self.in_atomic_block_mongo:

django_mongodb_backend/compiler.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,6 @@ def execute_sql(self, returning_fields=None):
678678
@wrap_database_errors
679679
def insert(self, docs, returning_fields=None):
680680
"""Store a list of documents using field columns as element names."""
681-
self.connection.validate_no_broken_transaction()
682681
inserted_ids = self.collection.insert_many(
683682
docs, session=self.connection.session
684683
).inserted_ids
@@ -762,7 +761,6 @@ def execute_sql(self, result_type):
762761

763762
@wrap_database_errors
764763
def update(self, criteria, pipeline):
765-
self.connection.validate_no_broken_transaction()
766764
return self.collection.update_many(
767765
criteria, pipeline, session=self.connection.session
768766
).matched_count

django_mongodb_backend/query.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ def __repr__(self):
6161
@wrap_database_errors
6262
def delete(self):
6363
"""Execute a delete query."""
64-
self.compiler.connection.validate_no_broken_transaction()
6564
if self.compiler.subqueries:
6665
raise NotSupportedError("Cannot use QuerySet.delete() when a subquery is required.")
6766
return self.compiler.collection.delete_many(
@@ -74,7 +73,6 @@ def get_cursor(self):
7473
Return a pymongo CommandCursor that can be iterated on to give the
7574
results of the query.
7675
"""
77-
self.compiler.connection.validate_no_broken_transaction()
7876
return self.compiler.collection.aggregate(
7977
self.get_pipeline(), session=self.compiler.connection.session
8078
)

django_mongodb_backend/transaction.py

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from contextlib import ContextDecorator
22

3-
from django.db import DEFAULT_DB_ALIAS, DatabaseError, Error
3+
from django.db import DEFAULT_DB_ALIAS, DatabaseError
44
from django.db.transaction import get_connection
55

66

@@ -30,82 +30,61 @@ class Atomic(ContextDecorator):
3030
`with oa:` multiple times.
3131
3232
Since database connections are thread-local, this is thread-safe.
33+
34+
Simplified from django.db.transaction.
3335
"""
3436

3537
def __init__(self, using):
3638
self.using = using
3739

3840
def __enter__(self):
3941
connection = get_connection(self.using)
40-
if not connection.in_atomic_block_mongo:
41-
# Reset state when entering an outermost atomic block.
42-
connection.needs_rollback_mongo = False
43-
4442
if connection.in_atomic_block_mongo:
45-
# We're already in a transaction. Increment the number of nested atomics.
43+
# If we're already in an atomic(), track the number of nested calls.
4644
connection.nested_atomics += 1
4745
else:
46+
# Start a transaction for the outermost atomic().
4847
connection._start_transaction()
4948
connection.in_atomic_block_mongo = True
5049

51-
if connection.in_atomic_block_mongo:
52-
connection.atomic_blocks_mongo.append(self)
53-
5450
def __exit__(self, exc_type, exc_value, traceback):
5551
connection = get_connection(self.using)
56-
57-
if connection.in_atomic_block_mongo:
58-
connection.atomic_blocks_mongo.pop()
59-
6052
if connection.nested_atomics:
6153
connection.nested_atomics -= 1
6254
else:
63-
# Prematurely unset this flag to allow using commit or rollback.
6455
connection.in_atomic_block_mongo = False
6556
try:
66-
if exc_type is None and not connection.needs_rollback_mongo:
57+
if exc_type is None:
58+
# atomic() exited without an error.
6759
if connection.in_atomic_block_mongo:
68-
# Release savepoint if there is one
60+
# Do nothing for an inner atomic().
6961
pass
7062
else:
71-
# Commit transaction
63+
# Commit transaction.
7264
try:
7365
connection.commit_mongo()
7466
except DatabaseError:
75-
try:
76-
connection.rollback_mongo()
77-
except Error:
78-
# An error during rollback means that something
79-
# went wrong with the connection. Drop it.
80-
connection.close()
81-
raise
67+
connection.rollback_mongo()
8268
else:
83-
# This flag will be set to True again if there isn't a savepoint
84-
# allowing to perform the rollback at this level.
85-
connection.needs_rollback_mongo = False
69+
# atomic() exited with an error.
8670
if connection.in_atomic_block_mongo:
87-
# Mark for rollback
88-
connection.needs_rollback_mongo = True
71+
# Do nothing for an inner atomic().
72+
pass
8973
else:
90-
# Roll back transaction
91-
try:
92-
connection.rollback_mongo()
93-
except Error:
94-
# An error during rollback means that something
95-
# went wrong with the connection. Drop it.
96-
connection.close()
74+
# Rollback transaction.
75+
connection.rollback_mongo()
9776
finally:
98-
# Outermost block exit
9977
if (
10078
not connection.in_atomic_block_mongo
10179
and connection.run_commit_hooks_on_set_autocommit_on
10280
):
81+
# Run on_commit() callbacks after outermost atomic()
10382
connection.run_and_clear_commit_hooks()
10483

10584

10685
def atomic(using=None):
107-
# Bare decorator: @atomic -- although the first argument is called
108-
# `using`, it's actually the function being decorated.
86+
# Bare decorator: @atomic -- although the first argument is called `using`, it's
87+
# actually the function being decorated.
10988
if callable(using):
11089
return Atomic(DEFAULT_DB_ALIAS)(using)
11190
# Decorator: @atomic(...) or context manager: with atomic(...): ...

docs/source/topics/transactions.rst

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,7 @@ Controlling transactions
6868
This is mostly a concern for :exc:`~django.db.DatabaseError` and its subclasses
6969
such as :exc:`~django.db.IntegrityError`. After such an error, the transaction
7070
is broken and Django will perform a rollback at the end of the ``atomic``
71-
block. If you attempt to run database queries before the rollback happens,
72-
Django will raise a :class:`~django.db.transaction.TransactionManagementError`.
73-
You may also encounter this behavior when an ORM-related signal handler raises
74-
an exception.
71+
block.
7572

7673
.. admonition:: You may need to manually revert app state when rolling back a transaction.
7774

tests/transactions_/tests.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,7 @@ class Callable:
119119
def __call__(self):
120120
pass
121121

122-
# Must not raise an exception
123-
transaction.atomic(Callable())
122+
transaction.atomic(Callable()) # Must not raise an exception
124123

125124

126125
@skipIfDBFeature("_supports_transactions")

0 commit comments

Comments
 (0)