Ticket #15507: 15507.1.diff

File 15507.1.diff, 3.9 KB (added by ramiro, 4 years ago)

Patch updated with tests and doc modifications

  • django/db/backends/mysql/base.py

    diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
    a b  
    263263    def max_name_length(self):
    264264        return 64
    265265
     266    def savepoint_create_sql(self, sid):
     267        return "SAVEPOINT %s" % sid
     268
     269    def savepoint_commit_sql(self, sid):
     270        return "RELEASE SAVEPOINT %s" % sid
     271
     272    def savepoint_rollback_sql(self, sid):
     273        return "ROLLBACK TO SAVEPOINT %s" % sid
     274
    266275class DatabaseWrapper(BaseDatabaseWrapper):
    267276    vendor = 'mysql'
    268277    operators = {
     
    330339            self.connection = Database.connect(**kwargs)
    331340            self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
    332341            self.connection.encoders[SafeString] = self.connection.encoders[str]
     342            self.features.uses_savepoints = \
     343                self.get_server_version() >= (5, 0, 3)
    333344            connection_created.send(sender=self.__class__, connection=self)
    334345        cursor = CursorWrapper(self.connection.cursor())
    335346        return cursor
  • docs/releases/1.4.txt

    diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt
    a b  
    238238* It is now possible to load fixtures containing forward references when using
    239239  MySQL with the InnoDB database engine.
    240240
     241* The MySQL database backend supports taking advantage of savepoint as featured
     242  by MySQL version 5.0.3 or newer with the InnoDB storage engine.
     243
    241244.. _backwards-incompatible-changes-1.4:
    242245
    243246Backwards incompatible changes in 1.4
  • docs/topics/db/transactions.txt

    diff --git a/docs/topics/db/transactions.txt b/docs/topics/db/transactions.txt
    a b  
    227227
    228228A savepoint is a marker within a transaction that enables you to roll back
    229229part of a transaction, rather than the full transaction. Savepoints are
    230 available to the PostgreSQL 8 and Oracle backends. Other backends will
    231 provide the savepoint functions, but they are empty operations - they won't
    232 actually do anything.
     230available to the PostgreSQL 8, Oracle and MySQL (version 5.0.3 and newer, when
     231using the InnoDB storage bckend) backends. Other backends will provide the
     232savepoint functions, but they are empty operations - they won't actually do
     233anything.
     234
     235.. versionchanged:: 1.4
     236   Savepoint support when using the MySQL backend was added in Django 1.4
    233237
    234238Savepoints aren't especially useful if you are using the default
    235239``autocommit`` behavior of Django. However, if you are using
  • tests/regressiontests/transactions_regress/tests.py

    diff --git a/tests/regressiontests/transactions_regress/tests.py b/tests/regressiontests/transactions_regress/tests.py
    a b  
    162162            _ = User.objects.all()[0]
    163163        except:
    164164            self.fail("A transaction consisting of a failed operation was not closed.")
     165
     166
     167class SavepointTest(TransactionTestCase):
     168
     169    @skipUnlessDBFeature('uses_savepoints')
     170    def test_savepoint_commit(self):
     171        @commit_manually
     172        def work():
     173            mod = Mod.objects.create(fld=1)
     174            pk = mod.pk
     175            sid = transaction.savepoint()
     176            mod1 = Mod.objects.filter(pk=pk).update(fld=10)
     177            transaction.savepoint_commit(sid)
     178            mod2 = Mod.objects.get(pk=pk)
     179            transaction.commit()
     180            self.assertEqual(mod2.fld, 10)
     181
     182        work()
     183
     184    @skipUnlessDBFeature('uses_savepoints')
     185    def test_savepoint_rollback(self):
     186        @commit_manually
     187        def work():
     188            mod = Mod.objects.create(fld=1)
     189            pk = mod.pk
     190            sid = transaction.savepoint()
     191            mod1 = Mod.objects.filter(pk=pk).update(fld=20)
     192            transaction.savepoint_rollback(sid)
     193            mod2 = Mod.objects.get(pk=pk)
     194            transaction.commit()
     195            self.assertEqual(mod2.fld, 1)
     196
     197        work()
Back to Top