我想执行一个事务来删除一些值,然后在db中计数,如果结果是< 1,回滚,我尝试了以下代码:
@login_required
@csrf_exempt
@transaction.atomic
def update_user_groups(request):
if request.POST:
userId = request.POST['userId']
groups = request.POST.getlist('groups[]')
result = None
with transaction.atomic():
try:
GroupsUsers.objects.filter(user_id=int(userId)).delete()
for group in groups:
group_user = GroupsUsers()
group_user.user_id = userId
group_user.group_id = group
group_user.save()
count = UsersInAdmin.objects.all().count()
if count < 1:
transaction.commit()
else:
transaction.rollback()
except Exception, e:
result = e
return JsonResponse(result, safe=False)
谢谢,
答案 0 :(得分:2)
无法在原子块内手动提交或回滚事务。
相反,您可以在原子块内引发异常。如果块完成,则将提交事务。如果引发异常,则将回滚该事务。在原子块之外,您可以捕获异常并继续查看。
try:
with transaction.atomic():
do_stuff()
if ok_to_commit():
pass
else:
raise ValueError()
except ValueError:
pass
答案 1 :(得分:1)
我认为你应该再看看Django documentation about db transactions。
最相关的评论如下:
避免在原子内捕获异常!
当退出原子块时,Django会查看它是正常退出还是有异常来确定是提交还是回滚。如果你捕获并处理原子块中的异常,你可以向Django隐瞒问题已经发生的事实。这可能会导致意外行为。
根据文档调整示例,看起来您应该嵌套try
和with
块,如下所示:
@transaction.atomic
def update_user_groups(request):
# set your variables
try:
with transaction.atomic():
# do your for loop
if count < 1:
# You should probably make a more descriptive, non-generic exception
# see http://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python for more info
raise Exception('Count is less than one')
except:
handle_exception()