在Django中开始事务

3 投票
1 回答
2266 浏览
提问于 2025-04-16 15:52

我读了Django文档中关于事务管理的章节。根据我的理解,一旦调用了TransactionMiddleware,事务就会开始。然后通过使用@commit_on_success@commit_manually,我们可以控制事务的结束。

我想问的是,是否有办法在不完全去掉TransactionMiddleware的情况下控制事务的开始。我担心Django框架的很多部分实际上依赖于TransactionMiddleware的存在,所以我不想破坏它。我希望它能在所有视图中使用,除了我明确指定的那些应用程序的视图。最重要的是,我希望能够完全控制某一组视图的事务行为——从开始到结束。我应该采取什么方法?有没有外部的应用或库可以帮助我?事务是立即创建的,还是在第一次访问数据库时才创建?

1 个回答

4
  1. 事务是通过第一个数据库查询创建的。

  2. TransactionMiddleware 会自动对你所有的视图应用类似于 commit_on_success 的功能。你不需要特别去添加这个。虽然如此,commit_on_success 仍然很有用,特别是当你想在视图中调用某些特定的函数时。

  3. 支持嵌套事务。

那么,为什么需要控制事务的开始呢?如果你想只撤销部分更改,就应该使用嵌套事务来实现。

下面是我代码中的一个常见用例:

@transaction.commit_manually
def purchase(request, ...):
    try:
      ... # change some data
      _purchase(request, *args, **kwargs) # process purchase optimistically
    except PurchaseError, ex: # My own exception class for errors we know about
      _log_purchase(request, ex) # Save error in DB
      messages.error(ex.human_message())
      transaction.commit() # Save log entries
    except:
      transaction.rollback()
      raise
    else:
      transaction.commit()

@transaction.commit_on_success
def _purchase(request, ...):
    ...  

撰写回答