Ticket #16047: 16047.diff

File 16047.diff, 4.0 KB (added by Anssi Kääriäinen, 12 years ago)
  • django/db/backends/__init__.py

    diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
    index ebe8875..c943ff0 100644
    a b class BaseDatabaseWrapper(object):  
    108108        over to the surrounding block, as a commit will commit all changes, even
    109109        those from outside. (Commits are on connection level.)
    110110        """
    111         self._leave_transaction_management(self.is_managed())
    112         if self.transaction_state:
    113             del self.transaction_state[-1]
    114         else:
     111        try:
     112            self.transaction_state.pop()
     113        except IndexError:
    115114            raise TransactionManagementError("This code isn't under transaction "
    116                 "management")
     115                                             "management")
     116        # Note that it is intentional we pop first one entry from the
     117        # transaction_state stack, and then use the topmost entry (given by
     118        # is_managed()) for _leave_transaction_management(). Refs #16047.
     119        self._leave_transaction_management(self.is_managed())
    117120        if self._dirty:
    118121            self.rollback()
    119122            raise TransactionManagementError("Transaction managed block ended with "
  • tests/regressiontests/transactions_regress/tests.py

    diff --git a/tests/regressiontests/transactions_regress/tests.py b/tests/regressiontests/transactions_regress/tests.py
    index 5972263..202051d 100644
    a b  
    11from __future__ import absolute_import
    22
    33from django.core.exceptions import ImproperlyConfigured
    4 from django.db import connection, transaction
     4from django.db import connection, connections, transaction, DEFAULT_DB_ALIAS
    55from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError
    66from django.test import TransactionTestCase, skipUnlessDBFeature
    77from django.test.utils import override_settings
    8 from django.utils.unittest import skipIf
     8from django.utils.unittest import skipIf, skipUnless
    99
    1010from .models import Mod, M2mA, M2mB
    1111
    class TestTransactionClosing(TransactionTestCase):  
    174174        """
    175175        self.test_failing_query_transaction_closed()
    176176
     177class TestAutocommit(TransactionTestCase):
     178    @skipUnless(connection.vendor == 'postgresql',
     179                "This test only valid for PostgreSQL")
     180    def test_autocommit_restored(self):
     181        """
     182        If autocommit is enabled, the isolation level should return to
     183        autocommit when leaving transaction management. Refs #16047.
     184
     185        NOTE: The PostgreSQL specific part is the isolation
     186        level constants.
     187        """
     188        try:
     189            # We want a clean backend with autocommit = True, so
     190            # first we need to do a bit of work to have that.
     191            old_backend = connections[DEFAULT_DB_ALIAS]
     192            settings = old_backend.settings_dict.copy()
     193            settings['OPTIONS']['autocommit'] = True
     194            new_backend = old_backend.__class__(settings, DEFAULT_DB_ALIAS)
     195            connections[DEFAULT_DB_ALIAS] = new_backend
     196            self.assertTrue(connection.features.uses_autocommit)
     197            # Ready to do the actual test.
     198            transaction.enter_transaction_management()
     199            # Ok, are we in isolation level read committed
     200            self.assertEqual(connection.isolation_level, 2)
     201            transaction.managed(True)
     202            # Test stacking
     203            transaction.enter_transaction_management()
     204            transaction.leave_transaction_management()
     205            # We should still be in isolation level 2
     206            self.assertEqual(connection.isolation_level, 2)
     207            transaction.leave_transaction_management()
     208            # And finally back in autocommit
     209            self.assertEqual(connection.isolation_level, 0)
     210        finally:
     211            connections[DEFAULT_DB_ALIAS] = old_backend
     212
    177213
    178214class TestManyToManyAddTransaction(TransactionTestCase):
    179215    def test_manyrelated_add_commit(self):
Back to Top