Django有一个名为@transaction.commit_manually
的装饰器函数。我试图将参数传递给此装饰器(using=db)
。 db
根据业务规则的不同而不同,具体取决于使用的数据库。将当前数据库传递给此装饰器的最佳方法是什么?我试图使用内部函数,因此:
def func(db):
stuff = _business logic_
@transaction.commit_manually(using=db)
def do_transaction(stuff):
try:
stuff.save(using=db)
except:
transaction.rollback()
else:
transaction.commit()
do_transaction()
然而,这失败了。我在pdb
中发现的错误是内部块是“不在事务管理下”。我该如何克服这个问题?
来自pdb
的跟踪:
-> success = transactional_registration()
/usr/local/lib/python2.7/dist-packages/django/db/transaction.py(338)_commit_manually()
-> return func(*args, **kw)
> /home/syrion/dev/registration.py(59)transactional_registration()
-> transaction.rollback()
/usr/local/lib/python2.7/dist-packages/django/db/transaction.py(210)rollback()
-> set_clean(using=using)
/usr/local/lib/python2.7/dist-packages/django/db/transaction.py(125)set_clean()
-> raise TransactionManagementError("This code isn't under transaction management"
编辑:我修复了自己的问题。内部函数解决方案正常工作,但我需要使用using参数调用rollback()
和commit()
,即transaction.commit(using=db)
。我发现这不直观,但是......
答案 0 :(得分:1)
我在代码中经常使用它,因为我对ORM施加了很大的压力。由于我不是装饰器语法的忠实粉丝,所以我使用with
语句。
def do_transaction(stuff, db):
with transaction.commit_manually(using=db)
try:
stuff.save(using=db)
except:
transaction.rollback()
else:
transaction.commit(using=db)
这应该有效。但是,不确定您(using=db)
中是否需要transaction.rollback()
。我相信你可以对此进行研究。但您需要(using=db)
中的transaction.commit(using=db)
。