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
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
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)
34 ... raise Exception("I meant to do that")
36 >>> create_a_reporter_then_fail("Alice", "Smith")
37 Traceback (most recent call last):
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):
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):
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")
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")
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")
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):
98 TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK