mirror of
https://github.com/django/django.git
synced 2025-08-04 10:59:45 +00:00
Fixed #36318 -- Fixed incorrect rollback exception attribution in nested atomic blocks.
Signed-off-by: saJaeHyukc <wogur981208@gmail.com>
This commit is contained in:
parent
de1117ea8e
commit
9bfb250b1b
2 changed files with 26 additions and 0 deletions
|
@ -195,6 +195,7 @@ class Atomic(ContextDecorator):
|
|||
# Reset state when entering an outermost atomic block.
|
||||
connection.commit_on_exit = True
|
||||
connection.needs_rollback = False
|
||||
connection.rollback_exc = None
|
||||
if not connection.get_autocommit():
|
||||
# Pretend we're already in an atomic block to bypass the code
|
||||
# that disables autocommit to enter a transaction, and make a
|
||||
|
@ -278,6 +279,9 @@ class Atomic(ContextDecorator):
|
|||
# otherwise.
|
||||
if sid is None:
|
||||
connection.needs_rollback = True
|
||||
# Avoid shadowing an already assigned rollback exc.
|
||||
if connection.rollback_exc is None:
|
||||
connection.rollback_exc = exc_value
|
||||
else:
|
||||
try:
|
||||
connection.savepoint_rollback(sid)
|
||||
|
|
|
@ -359,6 +359,28 @@ class AtomicErrorsTests(TransactionTestCase):
|
|||
self.assertIsInstance(cm.exception.__cause__, IntegrityError)
|
||||
self.assertEqual(Reporter.objects.get(pk=r1.pk).last_name, "Haddock")
|
||||
|
||||
def test_atomic_prevents_queries_in_broken_transaction_cause_attribution(self):
|
||||
# Trigger a previous atomic rollback to populate cause.
|
||||
with self.assertRaises(Exception), transaction.atomic():
|
||||
raise Exception("First failure")
|
||||
|
||||
with (
|
||||
self.assertRaises(transaction.TransactionManagementError) as ctx,
|
||||
transaction.atomic(),
|
||||
):
|
||||
try:
|
||||
with transaction.atomic(savepoint=False):
|
||||
raise Exception("Second failure")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
with transaction.atomic(savepoint=False):
|
||||
raise Exception("Third failure")
|
||||
except Exception:
|
||||
pass
|
||||
Reporter.objects.count()
|
||||
self.assertEqual(str(ctx.exception.__cause__), "Second failure")
|
||||
|
||||
@skipIfDBFeature("atomic_transactions")
|
||||
def test_atomic_allows_queries_after_fixing_transaction(self):
|
||||
r1 = Reporter.objects.create(first_name="Archibald", last_name="Haddock")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue