1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #26627 -- Fixed on_commit callbacks execution order when callbacks make transactions.

This commit is contained in:
Barthelemy Dagenais 2016-05-17 10:54:57 -04:00 committed by Tim Graham
parent 4ff1e6ef58
commit a5c8072ab1
3 changed files with 22 additions and 6 deletions

View File

@ -617,12 +617,11 @@ class BaseDatabaseWrapper(object):
def run_and_clear_commit_hooks(self): def run_and_clear_commit_hooks(self):
self.validate_no_atomic_block() self.validate_no_atomic_block()
try: current_run_on_commit = self.run_on_commit
while self.run_on_commit: self.run_on_commit = []
sids, func = self.run_on_commit.pop(0) while current_run_on_commit:
func() sids, func = current_run_on_commit.pop(0)
finally: func()
self.run_on_commit = []
def copy(self, alias=None, allow_thread_sharing=None): def copy(self, alias=None, allow_thread_sharing=None):
""" """

View File

@ -17,3 +17,6 @@ Bugfixes
* Fixed a regression causing the cached template loader to crash when using * Fixed a regression causing the cached template loader to crash when using
lazy template names (:ticket:`26603`). lazy template names (:ticket:`26603`).
* Fixed ``on_commit`` callbacks execution order when callbacks make
transactions (:ticket:`26627`).

View File

@ -208,6 +208,20 @@ class TestConnectionOnCommit(TransactionTestCase):
self.assertDone([1]) self.assertDone([1])
def test_hook_in_hook(self):
def on_commit(i, add_hook):
with transaction.atomic():
if add_hook:
transaction.on_commit(lambda: on_commit(i + 10, False))
t = Thing.objects.create(num=i)
self.notify(t.num)
with transaction.atomic():
transaction.on_commit(lambda: on_commit(1, True))
transaction.on_commit(lambda: on_commit(2, True))
self.assertDone([1, 11, 2, 12])
def test_raises_exception_non_autocommit_mode(self): def test_raises_exception_non_autocommit_mode(self):
def should_never_be_called(): def should_never_be_called():
raise AssertionError('this function should never be called') raise AssertionError('this function should never be called')