|
7 | 7 | import django
|
8 | 8 | from asgiref.sync import sync_to_async
|
9 | 9 | from django.contrib.auth.models import User
|
10 |
| -from django.db import connection |
| 10 | +from django.db import connection, transaction |
11 | 11 | from django.db.models import Count
|
12 | 12 | from django.db.utils import DatabaseError
|
13 | 13 | from django.shortcuts import render
|
@@ -527,3 +527,93 @@ def test_aliases(self):
|
527 | 527 |
|
528 | 528 | query = self.panel._queries[-1]
|
529 | 529 | self.assertEqual(query[0], "replica")
|
| 530 | + |
| 531 | + def test_transaction_status(self): |
| 532 | + """ |
| 533 | + Test case for tracking the transaction status is properly associated with |
| 534 | + queries on PostgreSQL, and that transactions aren't broken on other database |
| 535 | + engines. |
| 536 | + """ |
| 537 | + self.assertEqual(len(self.panel._queries), 0) |
| 538 | + |
| 539 | + with transaction.atomic(): |
| 540 | + list(User.objects.all()) |
| 541 | + list(User.objects.using("replica").all()) |
| 542 | + |
| 543 | + with transaction.atomic(using="replica"): |
| 544 | + list(User.objects.all()) |
| 545 | + list(User.objects.using("replica").all()) |
| 546 | + |
| 547 | + with transaction.atomic(): |
| 548 | + list(User.objects.all()) |
| 549 | + |
| 550 | + list(User.objects.using("replica").all()) |
| 551 | + |
| 552 | + response = self.panel.process_request(self.request) |
| 553 | + self.panel.generate_stats(self.request, response) |
| 554 | + |
| 555 | + if connection.vendor == "postgresql": |
| 556 | + # Connection tracking is currently only implemented for PostgreSQL. |
| 557 | + self.assertEqual(len(self.panel._queries), 6) |
| 558 | + |
| 559 | + query = self.panel._queries[0] |
| 560 | + self.assertEqual(query[0], "default") |
| 561 | + self.assertIsNotNone(query[1]["trans_id"]) |
| 562 | + self.assertTrue(query[1]["starts_trans"]) |
| 563 | + self.assertTrue(query[1]["in_trans"]) |
| 564 | + self.assertFalse("end_trans" in query[1]) |
| 565 | + |
| 566 | + query = self.panel._queries[-1] |
| 567 | + self.assertEqual(query[0], "replica") |
| 568 | + self.assertIsNone(query[1]["trans_id"]) |
| 569 | + self.assertFalse("starts_trans" in query[1]) |
| 570 | + self.assertFalse("in_trans" in query[1]) |
| 571 | + self.assertFalse("end_trans" in query[1]) |
| 572 | + |
| 573 | + query = self.panel._queries[2] |
| 574 | + self.assertEqual(query[0], "default") |
| 575 | + self.assertIsNotNone(query[1]["trans_id"]) |
| 576 | + self.assertEqual( |
| 577 | + query[1]["trans_id"], self.panel._queries[0][1]["trans_id"] |
| 578 | + ) |
| 579 | + self.assertFalse("starts_trans" in query[1]) |
| 580 | + self.assertTrue(query[1]["in_trans"]) |
| 581 | + self.assertTrue(query[1]["ends_trans"]) |
| 582 | + |
| 583 | + query = self.panel._queries[3] |
| 584 | + self.assertEqual(query[0], "replica") |
| 585 | + self.assertIsNotNone(query[1]["trans_id"]) |
| 586 | + self.assertNotEqual( |
| 587 | + query[1]["trans_id"], self.panel._queries[0][1]["trans_id"] |
| 588 | + ) |
| 589 | + self.assertTrue(query[1]["starts_trans"]) |
| 590 | + self.assertTrue(query[1]["in_trans"]) |
| 591 | + self.assertTrue(query[1]["ends_trans"]) |
| 592 | + |
| 593 | + query = self.panel._queries[4] |
| 594 | + self.assertEqual(query[0], "default") |
| 595 | + self.assertIsNotNone(query[1]["trans_id"]) |
| 596 | + self.assertNotEqual( |
| 597 | + query[1]["trans_id"], self.panel._queries[0][1]["trans_id"] |
| 598 | + ) |
| 599 | + self.assertNotEqual( |
| 600 | + query[1]["trans_id"], self.panel._queries[3][1]["trans_id"] |
| 601 | + ) |
| 602 | + self.assertTrue(query[1]["starts_trans"]) |
| 603 | + self.assertTrue(query[1]["in_trans"]) |
| 604 | + self.assertTrue(query[1]["ends_trans"]) |
| 605 | + |
| 606 | + query = self.panel._queries[5] |
| 607 | + self.assertEqual(query[0], "replica") |
| 608 | + self.assertIsNone(query[1]["trans_id"]) |
| 609 | + self.assertFalse("starts_trans" in query[1]) |
| 610 | + self.assertFalse("in_trans" in query[1]) |
| 611 | + self.assertFalse("end_trans" in query[1]) |
| 612 | + else: |
| 613 | + # Ensure that nothing was recorded for other database engines. |
| 614 | + self.assertTrue(self.panel._queries) |
| 615 | + for query in self.panel._queries: |
| 616 | + self.assertFalse("trans_id" in query[1]) |
| 617 | + self.assertFalse("starts_trans" in query[1]) |
| 618 | + self.assertFalse("in_trans" in query[1]) |
| 619 | + self.assertFalse("end_trans" in query[1]) |
0 commit comments