跨多个视图拆分交易

时间:2016-11-16 11:28:38

标签: django

我正试图弄清楚如何跨多个视图拆分事务。这就是我的想法:

  1. 我有一个创建大量记录的视图(全部打包到一个事务中);
  2. 该视图提供了有关这些更改的一些信息,以及一个允许用户接受或拒绝的表单;
  3. 根据用户的选择,应该提交或回滚交易。
  4. 我目前看到的代码如下:

    @transaction.non_atomic_requests
    def record_results(request):
       if request.method=='POST':
         if "approve" in request.POST:
           transaction.commit()
           transaction.set_autocommit(True)
         if "reject" in request.POST:
           transaction.rollback()
         # Turn AUTOCOMMIT back on again.
         transaction.set_autocommit(True)
         return render(request, 'updated.html')
    
       approve = ApproveForm()
       # Turn off AUTOCOMMIT.
       transaction.set_autocommit(False)
       # Create records here.
       # [...]
       context = {
           'approve': approve,
       }
       return render(request, 'accept.html', context)
    

    根据我对文档的理解,我认为这样可行。但是,它并没有像我预期的那样,所以我怀疑我的理解是有缺陷的。

    如果我注释掉transaction.set_autocommit(False),那么数据会被提交,但是会立即而不是在获得批准后提交。如果包含transaction.set_autocommit(False),则根本不会提交任何数据。

    问题可能是由于事务在视图的两次调用中被分开了吗?我在同一视图中也使用request.session。这有影响吗?

    任何帮助或建议表示赞赏。或者,如果对审批流程有更好的总体方法,我很乐意将其作为替代方案。

    我正在使用MySQL上的InnoDB表。

    谢谢你,最诚挚的问候,安德鲁。

1 个答案:

答案 0 :(得分:1)

事务是进程中单个线程的本地事务(因为连接是,并且事务绑定到单个连接),并且请求被路由到任意进程中的任意线程。即使使用单个线程和进程,也无法保证中间没有其他请求 - 并且单个线程服务请求会通过禁止任何并发性来绝对杀死站点的性能和可伸缩性。事务还阻止其他线程使用和更改相同的数据,因此事务应该尽可能短,或者您将再次阻止并发请求完成。

您可以 - 假设原始更改基于表单 - 使用隐藏输入在确认页面上呈现相同的表单,而不将数据保存到数据库。当用户批准更改时,您具有与表单数据相同的输入,并且您可以在确认请求期间轻松保存数据。