【问题标题】:atomic transaction is not working django rest原子事务不起作用 django rest
【发布时间】:2017-01-26 17:34:39
【问题描述】:

我正在使用 DRF、基于 API 视图类的视图、发布方法。 参数是:文件 逻辑:对文件进行一些验证并逐步保存文件(不同类型的对象) 如果在保存文件的其余部分时发生异常,我正在尝试回滚事务。我设置'ATOMIC_REQUESTS':True

class SaveXMlFile(APIView):
   authentication_classes = [TokenAuthentication]
   permission_classes = [IsAuthenticated]
   parser_classes = [FormParser, MultiPartParser]

   def post(self, request):
      """
          Save xml file
          ---
          # inputs
          parameters:
              - name: game_log_file
                description: Game log file
                type: file
                required: true
                paramType: post
                allowMultiple: false
      """
      try:
          # import pdb; pdb.set_trace()
          game_log_file = request.data['game_log_file']
          file_store = FileStore.objects.create(uploaded_file=game_log_file)
          xml_file_processing = ProcessXmlFile(file_store)
          already_saved = xml_file_processing.was_file_saved()
          player_exists = xml_file_processing.player_exists()
          if already_saved:
              file_store.delete()
              return Response({"info": "File was saved previously, no action taken place this time."}, status=200)
          if not player_exists:
              file_store.delete()
              return Response({"info":  "No player exists in the database, ask your administrator to create some."}, status=200)
          xml_file_processing.save()
          file_store.delete()
          return Response({"success": "File has been saved."}, status=status.HTTP_201_CREATED)
      except Exception as err:
          error = "{0}".format(str(err))
          return JsonResponse({'exception': error}, status=500)

当文件的一半已保存但提交的事务不回滚时,我故意抛出异常,即使在此过程中引发异常。

任何想法都将不胜感激。

【问题讨论】:

标签: django django-rest-framework


【解决方案1】:

您应该阅读更多有关事务如何与 Django 一起工作的内容。 由于您正在捕获异常,因此无论您的响应代码是什么,Django 都会看到一切正常并提交事务。取自https://docs.djangoproject.com/en/1.10/topics/db/transactions/#tying-transactions-to-http-requests

它是这样工作的。在调用视图函数之前,Django 会启动一个 交易。如果响应没有问题,Django 提交事务。如果视图产生异常,Django 回滚事务。

因此,由于您正在捕获异常并返回响应,Django 认为没有理由执行回滚。

【讨论】:

    【解决方案2】:

    这里有两个独立的东西。首先,当发生错误时,DRF 会自行引发 500 响应(因此无需捕获异常并显式地引发 500)。其次,你也可以考虑像这样应用 method_decorator:

    from django.utils.decorators import method_decorator
    from django.db.transaction import atomic
    
    @method_decorator(atomic, name='dispatch')
    class MyView(APIView):
      ....
    

    这背后的主要理由是,由于性能损失,使用 ATOMIC_REQUESTS 设置为 True 可能并不总是可取的,但您仍然可能希望将一些特定视图包装在原子块中。当然在这种情况下你可以使用

    with atomic():
      ... your code
    

    因为您可以访问方法本身,但这有点离题:)

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      对于未来的访客(假设时间旅行

      根据经验...

      在进行交易时切勿使用 try...catch !因为,使用事务,您试图解决不一致的问题....但是,使用 try...catch,您隐藏了不一致,以至于事务无法回滚。

      【讨论】:

        猜你喜欢
        • 2016-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-16
        • 1970-01-01
        • 2019-09-15
        • 2018-12-09
        • 1970-01-01
        相关资源
        最近更新 更多