summaryrefslogtreecommitdiff
path: root/tests/transactions
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2014-07-28 14:30:41 +0200
committerAymeric Augustin <aymeric.augustin@m4x.org>2014-07-28 14:30:41 +0200
commit729e4ae4f0730585ac4640e7fa3aa06374677ff2 (patch)
treeed724443e2dfc55150a518959ef44c299b6a9e71 /tests/transactions
parent53a61d82b38b7c39fa8ec4bd3047014694e96f60 (diff)
downloaddjango-729e4ae4f0730585ac4640e7fa3aa06374677ff2.tar.gz
Fixed #23074 -- Avoided leaking savepoints in atomic.
Thanks Chow Loong Jin for the report and the initial patch.
Diffstat (limited to 'tests/transactions')
-rw-r--r--tests/transactions/tests.py22
1 files changed, 22 insertions, 0 deletions
diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py
index 72e600d41d..005df0ba91 100644
--- a/tests/transactions/tests.py
+++ b/tests/transactions/tests.py
@@ -403,3 +403,25 @@ class AtomicMiscTests(TransactionTestCase):
pass
# Must not raise an exception
transaction.atomic(Callable())
+
+ @skipUnlessDBFeature('can_release_savepoints')
+ def test_atomic_does_not_leak_savepoints_on_failure(self):
+ # Regression test for #23074
+
+ # Expect an error when rolling back a savepoint that doesn't exist.
+ # Done outside of the transaction block to ensure proper recovery.
+ with self.assertRaises(Error):
+
+ # Start a plain transaction.
+ with transaction.atomic():
+
+ # Swallow the intentional error raised in the sub-transaction.
+ with six.assertRaisesRegex(self, Exception, "Oops"):
+
+ # Start a sub-transaction with a savepoint.
+ with transaction.atomic():
+ sid = connection.savepoint_ids[-1]
+ raise Exception("Oops")
+
+ # This is expected to fail because the savepoint no longer exists.
+ connection.savepoint_rollback(sid)