后端在生成订单表的时候,牵扯到如下的知识点:
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的事务隔离级别
打开配置文件
修改隔离级别