
并发处理 Django乐观锁的实现
发布日期:2021-05-14 23:02:04
浏览次数:18
分类:精选文章
本文共 1859 字,大约阅读时间需要 6 分钟。
商品超卖问题:多个用户同时下单同一个商品时,可能会出现资源竞争问题,导致库存结果出现异常
乐观锁解决:
乐观锁并不是真正的锁,只是更新数据的时候多加一层判断
更新的时候判断此时库存是否和之前查询的库存一样,如果一样则表示没人修改,可以进行更新;否则表示有人抢过该资源,不再进行更新。类似下面操作:
update tb_sku set stock=2 where id=1 and stock=7;
SKU.objects.filter(id=1, stock=7).update(stock=2)
思路:
创建保存点
查询库存
更新库存时,将之前查询的库存和商品id一起作为更新的条件
当受影响行为0表示更新失败,回滚到保存点(没有操作数据库的时候)
重新查询,重复到n次不成功返回错误 (这里while True 直到库存为0停止)
示例:
from django.db import transaction# 部分代码使用事物with transaction.atomic(): # 创建保存点 save_id = transaction.savepoint() try: # 生成订单信息 order = OrderInfo.objects.create( ... ) # 从redis取购物车要结算的商品数据(省略写法) ... cart = {shu.id: sku_count, ...} while True: # 直到没有库存为止 sku = SKU.objects.get(pk=sku_id) # 不加锁查询 # 购物车商品数量 count = cart[shu.id] # 获取原始库存 origin_stock = sku.stock # 判断商品库存是否充足 if origin_stock < count: # 库存不足 raise serializers.ValidationError('库存不足') # 演示并发请求 import time time.sleep(5) # 记录原来的值 origin_sales = sku.sales # 计算要更新的值 new_stock = origin_stock - count new_sales = origin_sales + count # 返回受影响的行数 ret = SKU.objects.filter(id=sku.id,stock=origin_stock).update(stock=new_stock,sales=new_sales) if ret == 0: # 更新成功,进入下次循环重新判断 continue else: # 保存订单商品数据 ... # 更新成功,退出while循环 break ... except Exception as e: # 提交保存点 transaction.savepoint_rollback(save_id) raise serializers.ValidationError('下单失败') # 提交事务 transaction.savepoint_commit(save_id) # 清除购物车中已经结算的商品 ... return order
发表评论
最新留言
很好
[***.229.124.182]2025年04月24日 03时52分10秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
04_Mysql配置文件(重要参数)
2021-05-09
JavaSE总结
2021-05-09
手动造轮子——基于.NetCore的RPC框架DotNetCoreRpc
2021-05-09
Python IO编程
2021-05-09
CSS入门总结
2021-05-09
使用 TortoiseGit 时,报 Access denied 错误
2021-05-09
基于 HTML5 WebGL 的污水处理厂泵站自控系统
2021-05-09
django-表单之模型表单渲染(六)
2021-05-09
c++之程序流程控制
2021-05-09
spring-boot-2.0.3之redis缓存实现,不是你想的那样哦!
2021-05-09
有道云笔记 同步到我的博客园
2021-05-09
李笑来必读书籍整理
2021-05-09
Hadoop(十六)之使用Combiner优化MapReduce
2021-05-09
《机器学习Python实现_10_06_集成学习_boosting_gbdt分类实现》
2021-05-09
CoreCLR源码探索(八) JIT的工作原理(详解篇)
2021-05-09
flume使用中的一些常见错误解决办法 (地址已经使用)
2021-05-10
andriod 开发错误记录
2021-05-10
C语言编译错误列表
2021-05-10