from django.db.transaction import managed, enter_transaction_management, is_dirty, rollback, commit, leave_transaction_management, _transaction_func
import threading
# storage of nested count
_tl = threading.local()
def nested_commit_on_success(using=None):
def entering(using):
lev = getattr(_tl,"level",0)
lev += 1
_tl.level = lev
if lev >= 2: # is it nested ?
return # yes it's nested, do nothing
else:
# first time, enter transaction
enter_transaction_management(using=using)
managed(True, using=using)
def exiting(exc_value, using):
lev = _tl.level
_tl.level -= 1
if lev >= 2: # is it nested ?
return # yes, do nothing
# last time, must do correct transaction ending
try:
if exc_value is not None:
if is_dirty(using=using):
rollback(using=using)
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)
Comments