Commit 14cddf51 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Merged branch 'database-level-autocommit'.

Fixed #2227: `atomic` supports nesting.
Fixed #6623: `commit_manually` is deprecated and `atomic` doesn't suffer from this defect.
Fixed #8320: the problem wasn't identified, but the legacy transaction management is deprecated.
Fixed #10744: the problem wasn't identified, but the legacy transaction management is deprecated.
Fixed #10813: since autocommit is enabled, it isn't necessary to rollback after errors any more.
Fixed #13742: savepoints are now implemented for SQLite.
Fixed #13870: transaction management in long running processes isn't a problem any more, and it's documented.
Fixed #14970: while it digresses on transaction management, this ticket essentially asks for autocommit on PostgreSQL.
Fixed #15694: `atomic` supports nesting.
Fixed #17887: autocommit makes it impossible for a connection to stay "idle of transaction".
parents 9cec689e e654180c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -434,6 +434,7 @@ answer newbie questions, and generally made Django that much better:
    Andreas Pelme <andreas@pelme.se>
    permonik@mesias.brnonet.cz
    peter@mymart.com
    Christophe Pettus <xof@thebuild.com>
    pgross@thoughtworks.com
    phaedo <http://phaedo.cx/>
    phil@produxion.net
+0 −4
Original line number Diff line number Diff line
@@ -555,10 +555,6 @@ class LayerMapping(object):
                    except SystemExit:
                        raise
                    except Exception as msg:
                        if self.transaction_mode == 'autocommit':
                            # Rolling back the transaction so that other model saves
                            # will work.
                            transaction.rollback_unless_managed()
                        if strict:
                            # Bailing out if the `strict` keyword is set.
                            if not silent:
+0 −1
Original line number Diff line number Diff line
@@ -74,7 +74,6 @@ class SessionStore(SessionBase):
    @classmethod
    def clear_expired(cls):
        Session.objects.filter(expire_date__lt=timezone.now()).delete()
        transaction.commit_unless_managed()


# At bottom to avoid circular import
+1 −6
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ except ImportError:

from django.conf import settings
from django.core.cache.backends.base import BaseCache
from django.db import connections, router, transaction, DatabaseError
from django.db import connections, router, DatabaseError
from django.utils import timezone, six
from django.utils.encoding import force_bytes

@@ -70,7 +70,6 @@ class DatabaseCache(BaseDatabaseCache):
            cursor = connections[db].cursor()
            cursor.execute("DELETE FROM %s "
                           "WHERE cache_key = %%s" % table, [key])
            transaction.commit_unless_managed(using=db)
            return default
        value = connections[db].ops.process_clob(row[1])
        return pickle.loads(base64.b64decode(force_bytes(value)))
@@ -124,10 +123,8 @@ class DatabaseCache(BaseDatabaseCache):
                               [key, b64encoded, connections[db].ops.value_to_db_datetime(exp)])
        except DatabaseError:
            # To be threadsafe, updates/inserts are allowed to fail silently
            transaction.rollback_unless_managed(using=db)
            return False
        else:
            transaction.commit_unless_managed(using=db)
            return True

    def delete(self, key, version=None):
@@ -139,7 +136,6 @@ class DatabaseCache(BaseDatabaseCache):
        cursor = connections[db].cursor()

        cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key])
        transaction.commit_unless_managed(using=db)

    def has_key(self, key, version=None):
        key = self.make_key(key, version=version)
@@ -184,7 +180,6 @@ class DatabaseCache(BaseDatabaseCache):
        table = connections[db].ops.quote_name(self._table)
        cursor = connections[db].cursor()
        cursor.execute('DELETE FROM %s' % table)
        transaction.commit_unless_managed(using=db)

# For backwards compatibility
class CacheClass(DatabaseCache):
+10 −2
Original line number Diff line number Diff line
@@ -6,10 +6,10 @@ import types

from django import http
from django.conf import settings
from django.core import exceptions
from django.core import urlresolvers
from django.core import signals
from django.core.exceptions import MiddlewareNotUsed, PermissionDenied
from django.db import connections, transaction
from django.utils.encoding import force_text
from django.utils.module_loading import import_by_path
from django.utils import six
@@ -65,6 +65,13 @@ class BaseHandler(object):
        # as a flag for initialization being complete.
        self._request_middleware = request_middleware

    def make_view_atomic(self, view):
        if getattr(view, 'transactions_per_request', True):
            for db in connections.all():
                if db.settings_dict['ATOMIC_REQUESTS']:
                    view = transaction.atomic(using=db.alias)(view)
        return view

    def get_response(self, request):
        "Returns an HttpResponse object for the given HttpRequest"
        try:
@@ -101,8 +108,9 @@ class BaseHandler(object):
                            break

                if response is None:
                    wrapped_callback = self.make_view_atomic(callback)
                    try:
                        response = callback(request, *callback_args, **callback_kwargs)
                        response = wrapped_callback(request, *callback_args, **callback_kwargs)
                    except Exception as e:
                        # If the view raised an exception, run it through exception
                        # middleware, and if the exception middleware returns a
Loading