django:在transaction.atomic()中提交并引发

时间:2016-11-23 13:48:12

标签: python django transactions django-orm

我们正在尝试从commit_manually迁移到atomic,因此我们可以在遗留项目中将Django升级到至少1.8。在大多数情况下,我们需要做类似的事情:

with transaction.atomic():
    obj = Entity.objects.select_for_update().get(pk=pk)
    try:
        obj.do_something()
        obj.set_some_status()
        obj.save()
    except SomeException:
        obj.set_failed_flag()
        obj.save()
        raise

因为被调用者需要此异常信息才能继续执行某个流程。但在这种情况下,事务/保存点将被回滚,这不是我们想要的,因为我们希望提交obj.set_failed_flag()。在同一个原子块中设置它似乎也是合乎逻辑的,因为我们已经为这个对象设置了一个锁定的行。

任何想法/模式?提前谢谢!

P.S。旧手动交易管理很容易!

P.P.S。我们也使用例外来“提前退出”并转移到一些旗帜等会带来一堆乱七八糟的东西,我个人很乐意避免它。

2 个答案:

答案 0 :(得分:1)

假设CallbackPath不是数据库异常,您只需保存它并将其提升到原子块之外:

/umbraco/surface/UmbracoIdentityAccount/LinkLoginCallback

如果您发现这个过于冗长且需要经常执行,您可能可以编写一个上下文管理器作为SomeException的代理,但在某些情况下不会触发回滚。

最后,请注意Django仍有manual transaction management

答案 1 :(得分:1)

除了已经发布的答案,如果有嵌套方法,你在链中更高的位置启动原子块,它有助于使用以下内容:

transaction.on_commit(lambda: method_that_raises_exception())

这样就会在事务提交后引发异常。