Fixed #14550 -- fixed the behavior of commit_on_success to exit the transaction properly. This was a bug introduced in [14288]. Thanks to Justin for the report and Florian Apolloner for help debugging.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14343 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor 2010-10-24 17:25:49 +00:00
parent eccc42a8c7
commit 01e2be557b
3 changed files with 46 additions and 9 deletions

View File

@ -345,16 +345,19 @@ def commit_on_success(using=None):
managed(True, using=using) managed(True, using=using)
def exiting(exc_value, using): def exiting(exc_value, using):
if exc_value is not None: try:
if is_dirty(using=using): if exc_value is not None:
rollback(using=using) if is_dirty(using=using):
else:
if is_dirty(using=using):
try:
commit(using=using)
except:
rollback(using=using) rollback(using=using)
raise else:
if is_dirty(using=using):
try:
commit(using=using)
except:
rollback(using=using)
raise
finally:
leave_transaction_management(using=using)
return _transaction_func(entering, exiting, using) return _transaction_func(entering, exiting, using)

View File

@ -113,6 +113,25 @@ class TransactionTests(TransactionTestCase):
remove_comitted_on_success("Alice") remove_comitted_on_success("Alice")
self.assertEqual(list(Reporter.objects.all()), []) self.assertEqual(list(Reporter.objects.all()), [])
@skipUnlessDBFeature('supports_transactions')
def test_commit_on_success_exit(self):
@transaction.autocommit()
def gen_reporter():
@transaction.commit_on_success
def create_reporter():
Reporter.objects.create(first_name="Bobby", last_name="Tables")
create_reporter()
# Much more formal
r = Reporter.objects.get()
r.first_name = "Robert"
r.save()
gen_reporter()
r = Reporter.objects.get()
self.assertEqual(r.first_name, "Robert")
@skipUnlessDBFeature('supports_transactions') @skipUnlessDBFeature('supports_transactions')
def test_manually_managed(self): def test_manually_managed(self):
""" """
@ -146,6 +165,7 @@ class TransactionTests(TransactionTestCase):
using_manually_managed_mistake using_manually_managed_mistake
) )
class TransactionRollbackTests(TransactionTestCase): class TransactionRollbackTests(TransactionTestCase):
def execute_bad_sql(self): def execute_bad_sql(self):
cursor = connection.cursor() cursor = connection.cursor()

View File

@ -78,6 +78,20 @@ class TransactionContextManagerTests(TransactionTestCase):
self.assertQuerysetEqual(Reporter.objects.all(), []) self.assertQuerysetEqual(Reporter.objects.all(), [])
@skipUnlessDBFeature('supports_transactions')
def test_commit_on_success_exit(self):
with transaction.autocommit():
with transaction.commit_on_success():
Reporter.objects.create(first_name="Bobby", last_name="Tables")
# Much more formal
r = Reporter.objects.get()
r.first_name = "Robert"
r.save()
r = Reporter.objects.get()
self.assertEqual(r.first_name, "Robert")
@skipUnlessDBFeature('supports_transactions') @skipUnlessDBFeature('supports_transactions')
def test_manually_managed(self): def test_manually_managed(self):
""" """