thirdparty/google_appengine/lib/django/tests/modeltests/transactions/models.py
author Lennard de Rijk <ljvderijk@gmail.com>
Sun, 12 Jul 2009 14:03:35 +0200
changeset 2610 95949d4c45d9
parent 109 620f9b141567
permissions -rwxr-xr-x
Add scope view for GradingSurveyGroup and set access checks. The access checks are now properly set for create, edit and show. To facilitate the scope view the access check have an extra check built in to ensure that a scope is actually present before cheking for an existing Program.

"""
15. Transactions

Django handles transactions in three different ways. The default is to commit
each transaction upon a write, but you can decorate a function to get
commit-on-success behavior. Alternatively, you can manage the transaction
manually.
"""

from django.db import models

class Reporter(models.Model):
    first_name = models.CharField(maxlength=30)
    last_name = models.CharField(maxlength=30)
    email = models.EmailField()

    def __str__(self):
        return "%s %s" % (self.first_name, self.last_name)

__test__ = {'API_TESTS':"""
>>> from django.db import connection, transaction
"""}

from django.conf import settings

building_docs = getattr(settings, 'BUILDING_DOCS', False)

if building_docs or settings.DATABASE_ENGINE != 'mysql':
    __test__['API_TESTS'] += """
# the default behavior is to autocommit after each save() action
>>> def create_a_reporter_then_fail(first, last):
...     a = Reporter(first_name=first, last_name=last)
...     a.save()
...     raise Exception("I meant to do that")
...
>>> create_a_reporter_then_fail("Alice", "Smith")
Traceback (most recent call last):
    ...
Exception: I meant to do that

# The object created before the exception still exists
>>> Reporter.objects.all()
[<Reporter: Alice Smith>]

# the autocommit decorator works exactly the same as the default behavior
>>> autocomitted_create_then_fail = transaction.autocommit(create_a_reporter_then_fail)
>>> autocomitted_create_then_fail("Ben", "Jones")
Traceback (most recent call last):
    ...
Exception: I meant to do that

# Same behavior as before
>>> Reporter.objects.all()
[<Reporter: Alice Smith>, <Reporter: Ben Jones>]

# With the commit_on_success decorator, the transaction is only comitted if the
# function doesn't throw an exception
>>> committed_on_success = transaction.commit_on_success(create_a_reporter_then_fail)
>>> committed_on_success("Carol", "Doe")
Traceback (most recent call last):
    ...
Exception: I meant to do that

# This time the object never got saved
>>> Reporter.objects.all()
[<Reporter: Alice Smith>, <Reporter: Ben Jones>]

# If there aren't any exceptions, the data will get saved
>>> def remove_a_reporter():
...     r = Reporter.objects.get(first_name="Alice")
...     r.delete()
...
>>> remove_comitted_on_success = transaction.commit_on_success(remove_a_reporter)
>>> remove_comitted_on_success()
>>> Reporter.objects.all()
[<Reporter: Ben Jones>]

# You can manually manage transactions if you really want to, but you
# have to remember to commit/rollback
>>> def manually_managed():
...     r = Reporter(first_name="Carol", last_name="Doe")
...     r.save()
...     transaction.commit()
>>> manually_managed = transaction.commit_manually(manually_managed)
>>> manually_managed()
>>> Reporter.objects.all()
[<Reporter: Ben Jones>, <Reporter: Carol Doe>]

# If you forget, you'll get bad errors
>>> def manually_managed_mistake():
...     r = Reporter(first_name="David", last_name="Davidson")
...     r.save()
...     # oops, I forgot to commit/rollback!
>>> manually_managed_mistake = transaction.commit_manually(manually_managed_mistake)
>>> manually_managed_mistake()
Traceback (most recent call last):
    ...
TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK
"""