答案是肯定的,Django中默认支持事务。
那就意味着, 一段代码:
from django.db import transaction
class UpdatePlan(APIView):
# authentication_classes = []
@transaction.atomic()
def post(self, request):
plan_id = request.data.get("plan_id", None)
resultList = request.data.get("busizArray", [])
attentions = request.data.get("attentions", None)
if not check_params_ok(plan_id):
return Response({"detail": "params lose"}, status=status.HTTP_202_ACCEPTED)
if not resultList:
return Response({"detail": "方案不能为空"}, status=status.HTTP_202_ACCEPTED)
try:
all_treatment = CareTreatment.objects.filter(plan_id=plan_id)
all_treatment.delete()
cp = CarePlan.objects.get(id=plan_id)
for i in resultList:
homeList=i.get('home')
for k in range(0,len(homeList)):
caredicts = homeList[k].get('home_care')
for caredict in caredicts:
goods = PlanGoods.objects.get(id=caredict.get('product_item_id'))
CareTreatment.objects.create(
goods=goods,
usage_tag=caredict.get('giftRemark'),
plan_id=cp,
order=caredict.get('order'),
plan=str(i.get("name"))+"方案",
group=k+1
)
advice = homeList[k].get('advice')
advice_id = advice["id"]
advice = advice["advice"]
if advice_id is not None:
cpa_ = CarePlanAdvices.objects.get(id=advice_id)
cpa_.advice = advice
cpa_.save()
if advice is not None:
CarePlanAdvices.objects.create(plan=str(i.get("name"))+"方案", plan_id=cp, group=k+1, advice=advice)
except Exception as e:
print(e)
result = {"detail": "提交院护方案失败"}
return Response(result,status=status.HTTP_202_ACCEPTED)
这段代码的核心部分包括 删除 和 新增 CareTreatment这张表数据, 两部分操作。
事实上,遇到一个问题,在新增报错的情况下,会导致删除成功,而新增没有成功。
那么这就不是一个合格的事务,至少是违反了原子性和一致性两大特点。
Django默认支持的事务去哪了呢?
Django默认是支持事务,Django 如何显示的使用事务呢?
有三种方法:
- 装饰器的用法
from django.db import transaction
@transaction.atomic
def post(request):
pass
# 事务的代码
- with语句的用法
from django.db import transaction
def post(request):
with transaction.atomic():
pass
# 事务的代码
- 保存点的用法
from django.db import transaction
# 创建保存点
save_id = transaction.savepoint()
# 回滚
transaction.savepoint_rollback(save_id)
# 提交
transaction.savepoint_commit(save_id)
其实我们可以理解django默认支持的事务是第一种形式的。
Django也没想到我们在实现View的时候居然有多重的操作。
所以我们需要用后两种形式对我们多重操作的自定义事务。
第二种形式优化后:
class UpdatePlan(APIView):
def post(self, request):
plan_id = request.data.get("plan_id", None)
resultList = request.data.get("busizArray", [])
attentions = request.data.get("attentions", None)
if not check_params_ok(plan_id):
return Response({"detail": "params lose"}, status=status.HTTP_202_ACCEPTED)
if not resultList:
return Response({"detail": "方案不能为空"}, status=status.HTTP_202_ACCEPTED)
try:
with transaction.atomic():
all_treatment = CareTreatment.objects.filter(plan_id=plan_id)
all_treatment.delete()
cp = CarePlan.objects.get(id=plan_id)
for i in resultList:
homeList=i.get('home')
for k in range(0,len(homeList)):
caredicts = homeList[k].get('home_care')
for caredict in caredicts:
goods = PlanGoods.objects.get(id=caredict.get('product_item_id'))
CareTreatment.objects.create(
goods=goods,
usage_tag=caredict.get('giftRemark'),
plan_id=cp,
order=caredict.get('order'),
plan=str(i.get("name"))+"方案",
group=k+1
)
advice = homeList[k].get('advice')
advice_id = advice["id"]
advice = advice["advice"]
if advice_id is not None:
cpa_ = CarePlanAdvices.objects.get(id=advice_id)
cpa_.advice = advice
cpa_.save()
if advice is not None:
CarePlanAdvices.objects.create(plan=str(i.get("name"))+"方案", plan_id=cp, group=k+1, advice=advice)
except Exception as e:
print(e)
result = {"detail": "提交院护方案失败"}
return Response(result,status=status.HTTP_202_ACCEPTED)
第三种形式优化后:
class UpdatePlan(APIView):
def post(self, request):
plan_id = request.data.get("plan_id", None)
resultList = request.data.get("busizArray", [])
attentions = request.data.get("attentions", None)
if not check_params_ok(plan_id):
return Response({"detail": "params lose"}, status=status.HTTP_202_ACCEPTED)
if not resultList:
return Response({"detail": "方案不能为空"}, status=status.HTTP_202_ACCEPTED)
save_id = transaction.savepoint()
try:
all_treatment = CareTreatment.objects.filter(plan_id=plan_id)
all_treatment.delete()
cp = CarePlan.objects.get(id=plan_id)
for i in resultList:
homeList=i.get('home')
for k in range(0,len(homeList)):
caredicts = homeList[k].get('home_care')
for caredict in caredicts:
goods = PlanGoods.objects.get(id=caredict.get('product_item_id'))
CareTreatment.objects.create(
goods=goods,
usage_tag=caredict.get('giftRemark'),
plan_id=cp,
order=caredict.get('order'),
plan=str(i.get("name"))+"方案",
group=k+1
)
advice = homeList[k].get('advice')
advice_id = advice["id"]
advice = advice["advice"]
if advice_id is not None:
cpa_ = CarePlanAdvices.objects.get(id=advice_id)
cpa_.advice = advice
cpa_.save()
if advice is not None:
CarePlanAdvices.objects.create(plan=str(i.get("name"))+"方案", plan_id=cp, group=k+1, advice=advice)
transaction.savepoint_commit(save_id)
except Exception as e:
print(e)
transaction.savepoint_rollback(save_id)
result = {"detail": "提交院护方案失败"}
return Response(result,status=status.HTTP_202_ACCEPTED)
这篇博客讨论了Django中事务管理的问题,指出在一段代码中,由于没有正确使用事务,导致了在新增操作失败时删除操作仍然执行,违反了事务的原子性和一致性。Django默认支持事务,但在这里需要显式使用`@transaction.atomic()`装饰器或`with transaction.atomic():`来包裹多条数据库操作。文章提供了优化后的代码示例,展示了如何通过事务确保所有操作要么全部成功,要么全部回滚,从而维护数据的完整性。
1086

被折叠的 条评论
为什么被折叠?



