django 保存订单乐观锁的使用

后端在生成订单表的时候,牵扯到如下的知识点:

1 事物

2 高并发

3 时间函数的使用
一,事务:

from django.db import transaction
 
save_id = transaction.savepoint()  # 创建保存点
 
transaction.savepoint_rollback(save_id)  # 回退(回滚)到保存点
 
transaction.savepoint_commit(save_id)  # 提交保存点

例子用法:

from django.db import transaction

with transaction.atomic():

  # 创建保存点
  save_ponit=transaction.savepoint()
       try:
          # 4、生成订单基本信息表
          order = OrderInfo.objects.create(
          ......
              )
     except:
                       transaction.savepoint_rollback(save_ponit)
                 
      else:
                        transaction.savepoint_commit(save_ponit)

二、 高并发
当多个用户同时去抢同一个商品的时候,就有可能会出现库存不足,把一些错误的数据保存到数据库中

在这里插入图片描述
解决的方法: 采用悲观锁,采用乐观锁,采用队列,排队下单

1,悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。

悲观锁用法:

使用原生的SQL语句
update tb_goodsinfo set stock=5 where id=1 and stock=10;
 
使用Django中的语法
GoodsInfo.objects.filter(id=1, stock=10).update(stock=5)
 
# GoodsInfo:模型类,  id:商品id,  stock:库存


三,乐观锁

顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,

先查询

from django.http import HttpResponse
from rest_framework.generics import GenericAPIView
from app01.models import GoodsInfo
 
class Goods(GenericAPIView):
    """ 购买商品 """
    def post(self, request):
        # 获取请求头中查询字符串数据
        goods_id = request.GET.get('goods_id')
        count = int(request.GET.get('count'))
 
        while True:
            # 查询商品对象
            goods = GoodsInfo.objects.filter(id=goods_id).first()
            # 获取原始库存
            origin_stock = goods.stock
 
            # 判断商品库存是否充足
            if origin_stock < count:
                return HttpResponse(content="商品库存不足", status=400)
 
            # 演示并发请求
            import time
            time.sleep(5)
 
            # 减少商品的库存数量,保存到数据库
            # goods.stock = origin_stock - count
            # goods.save()
            """ 使用乐观锁进行处理,一步完成数据库的查询和更新 """
            # update返回受影响的行数
            result = GoodsInfo.objects.filter(id=goods.id, stock=origin_stock).update(stock=origin_stock - count)
            if result == 0:
                # 表示更新失败,有人抢先购买了商品,重新获取库存信息,判断库存
                continue
 
            # 表示购买成功,退出 while 循环
            break
 
        return HttpResponse(content="操作成功", status=200)


四、需要修改MySQL的事务隔离级别
打开配置文件
在这里插入图片描述

修改隔离级别
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值