Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django models: managing transactions when commit_manually is deprecated

I'm running Django 1.4.11. I overrode the save() method of a Django model in a way similar to the following code:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
    # model definition

    @transaction.commit_manually
    def save(self, *args, **kwargs):
        try:
            super(self.__class__, self).save(*args, **kwargs)
            foo() # do_other_things
        except:
            transaction.rollback()
            raise
        else:
            transaction.commit()

When I run my code, sometimes I read this message in the Apache log:

RemovedInDjango18Warning: commit_manually is deprecated in favor of set_autocommit.

How can I implement the same logic with set_autocommit?

like image 951
floatingpurr Avatar asked Dec 11 '22 22:12

floatingpurr


2 Answers

The same logic would look like this:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
    # model definition

    def save(self, *args, **kwargs):
        transaction.set_autocommit(False)
        try:
            super(MyModel, self).save(*args, **kwargs)
            foo() # do_other_things
        except:
            transaction.rollback()
            raise
        else:
            transaction.commit()
        finally:
            transaction.set_autocommit(True)

However, this would be equivalent to using the atomic() decorator:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
    # model definition

    @transaction.atomic
    def save(self, *args, **kwargs):
        super(MyModel, self).save(*args, **kwargs)
        foo() # do_other_things

This will commit the transaction on a successful __exit__, and roll back in the case of an exception.

like image 139
knbk Avatar answered Mar 08 '23 23:03

knbk


For the example you have given you can just use transaction.atomic . If the code succeeds, the entire transaction will be committed. If there's an exception, the changes will be rolled back.

@transaction.atomic
def save(self, *args, **kwargs):
    super(self.__class__, self).save(*args, **kwargs)
    foo() # do_other_things
like image 29
Alasdair Avatar answered Mar 08 '23 23:03

Alasdair