我正在使用DRF,基于API View Class的视图,post方法。
参数是:file
逻辑:对文件进行一些验证并逐步保存文件(不同类型的对象)
我正在尝试回滚事务,如果在保存文件的其余部分时发生异常。我设置'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)
当有一半文件被保存但是已提交的事务不会回滚时,我故意抛出异常,甚至在此过程中引发了异常。
任何想法都会受到赞赏。
答案 0 :(得分:2)
您应该阅读更多关于事务如何与Django一起使用的内容。 由于您正在捕获异常,Django将看到一切正常并将提交事务,无论您的响应代码是什么。取自https://docs.djangoproject.com/en/1.10/topics/db/transactions/#tying-transactions-to-http-requests:
它的工作原理如下。在调用视图函数之前,Django启动了一个 交易。如果生成的响应没有问题,Django 提交交易。如果视图产生异常,Django 回滚交易。
因此,由于您正在捕获异常并返回响应,因此Django认为没有理由执行回滚。
答案 1 :(得分:2)
对于来自未来的访问者(假设时间旅行)
根据经验...
在进行交易时切勿使用 try...catch !!因为,通过事务,您正在尝试解决不一致的问题......但是,通过 try...catch,您隐藏了不一致,从而导致事务无法回滚。