Merged the queryset-refactor branch into trunk.
[fdr-django.git] / tests / modeltests / transactions / models.py
bloba3222cd511120151f31d20da8d606c05b8d87289
1 """
2 15. Transactions
4 Django handles transactions in three different ways. The default is to commit
5 each transaction upon a write, but you can decorate a function to get
6 commit-on-success behavior. Alternatively, you can manage the transaction
7 manually.
8 """
10 from django.db import models
12 class Reporter(models.Model):
13 first_name = models.CharField(max_length=30)
14 last_name = models.CharField(max_length=30)
15 email = models.EmailField()
17 def __unicode__(self):
18 return u"%s %s" % (self.first_name, self.last_name)
20 __test__ = {'API_TESTS':"""
21 >>> from django.db import connection, transaction
22 """}
24 from django.conf import settings
26 building_docs = getattr(settings, 'BUILDING_DOCS', False)
28 if building_docs or settings.DATABASE_ENGINE not in ('mysql', 'mysql_old'):
29 __test__['API_TESTS'] += """
30 # the default behavior is to autocommit after each save() action
31 >>> def create_a_reporter_then_fail(first, last):
32 ... a = Reporter(first_name=first, last_name=last)
33 ... a.save()
34 ... raise Exception("I meant to do that")
35 ...
36 >>> create_a_reporter_then_fail("Alice", "Smith")
37 Traceback (most recent call last):
38 ...
39 Exception: I meant to do that
41 # The object created before the exception still exists
42 >>> Reporter.objects.all()
43 [<Reporter: Alice Smith>]
45 # the autocommit decorator works exactly the same as the default behavior
46 >>> autocomitted_create_then_fail = transaction.autocommit(create_a_reporter_then_fail)
47 >>> autocomitted_create_then_fail("Ben", "Jones")
48 Traceback (most recent call last):
49 ...
50 Exception: I meant to do that
52 # Same behavior as before
53 >>> Reporter.objects.all()
54 [<Reporter: Alice Smith>, <Reporter: Ben Jones>]
56 # With the commit_on_success decorator, the transaction is only comitted if the
57 # function doesn't throw an exception
58 >>> committed_on_success = transaction.commit_on_success(create_a_reporter_then_fail)
59 >>> committed_on_success("Carol", "Doe")
60 Traceback (most recent call last):
61 ...
62 Exception: I meant to do that
64 # This time the object never got saved
65 >>> Reporter.objects.all()
66 [<Reporter: Alice Smith>, <Reporter: Ben Jones>]
68 # If there aren't any exceptions, the data will get saved
69 >>> def remove_a_reporter():
70 ... r = Reporter.objects.get(first_name="Alice")
71 ... r.delete()
72 ...
73 >>> remove_comitted_on_success = transaction.commit_on_success(remove_a_reporter)
74 >>> remove_comitted_on_success()
75 >>> Reporter.objects.all()
76 [<Reporter: Ben Jones>]
78 # You can manually manage transactions if you really want to, but you
79 # have to remember to commit/rollback
80 >>> def manually_managed():
81 ... r = Reporter(first_name="Carol", last_name="Doe")
82 ... r.save()
83 ... transaction.commit()
84 >>> manually_managed = transaction.commit_manually(manually_managed)
85 >>> manually_managed()
86 >>> Reporter.objects.all()
87 [<Reporter: Ben Jones>, <Reporter: Carol Doe>]
89 # If you forget, you'll get bad errors
90 >>> def manually_managed_mistake():
91 ... r = Reporter(first_name="David", last_name="Davidson")
92 ... r.save()
93 ... # oops, I forgot to commit/rollback!
94 >>> manually_managed_mistake = transaction.commit_manually(manually_managed_mistake)
95 >>> manually_managed_mistake()
96 Traceback (most recent call last):
97 ...
98 TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK
99 """