django实现悲观锁乐观锁

前期准备

python 复制代码
# 线上卖图书
	-图书表  图书名字,图书价格,库存字段
    -订单表: 订单id,订单名字
    
# 表准备
	class Book(models.Model):
        name = models.CharField(max_length=32)
        price = models.IntegerField()  #
        count = models.SmallIntegerField(verbose_name='库存')
    class Order(models.Model):
        order_id = models.CharField(max_length=64)
        order_name = models.CharField(max_length=32)
        
# 使用mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'lqz',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'USER': 'lqz',
        'PASSWORD': '123',
    }
}

# 创建lqz数据库

1.原生mysql悲观锁

python 复制代码
begin; # 开启事务

select * from goods where id = 1 for update;  # 行锁

# order表中加数据

update goods set stock = stock - 1 where id = 1; # 更新

commit; #提交事务

2.orm实现上述(悲观锁)

python 复制代码
#1  使用悲观锁实现下单
@transaction.atomic  # 整个过程在一个事物中---》改两个表:book表减库存,订单表生成记录
def seckill(request):
    # 锁住查询到的book对象,直到事务结束
    sid = transaction.savepoint() # 保存点
    # 悲观锁: select_for_update()
    # 加锁了--》行锁还是表锁? 分情况,都有可能
    #
    book = Book.objects.select_for_update().filter(pk=1).first()  # 加悲观锁,行锁,锁住当前行
    if book.count > 0:
        print('库存可以,下单')
        # 订单表插入一条
        Order.objects.create(order_id=str(datetime.datetime.now()), order_name='测试订单')
        # 库存-1,扣减的时候,判断库存是不是上面查出来的库存,如果不是,就回滚
        time.sleep(random.randint(1, 4))  # 模拟延迟
        book.count=book.count-1
        book.save()
        transaction.savepoint_commit(sid)  # 提交,释放行锁
        return HttpResponse('秒杀成功')
    else:
        transaction.savepoint_rollback(sid) #回滚,释放行锁
        return HttpResponse('库存不足,秒杀失败')

3 乐观锁秒杀--》库存还有,有的人就没成功

python 复制代码
# 2 乐观锁秒杀--普通版
@transaction.atomic
def seckill(request):
    # 锁住查询到的book对象,直到事务结束
    sid = transaction.savepoint()
    book = Book.objects.filter(pk=1).first()  # 没加锁
    count = book.count
    print('现在的库存为:%s' % count)
    if book.count > 0:
        print('库存可以,下单')
        Order.objects.create(order_id=str(datetime.datetime.now()), order_name='测试订单-乐观锁')
        # 库存-1,扣减的时候,判断库存是不是上面查出来的库存,如果不是,就回滚
        # time.sleep(random.randint(1, 4))  # 模拟延迟
        res = Book.objects.filter(pk=1, count=count).update(count=count - 1)
        if res >= 1:  # 表示修改成功
            transaction.savepoint_commit(sid)
            return HttpResponse('秒杀成功')
        else:  # 修改不成功,回滚
            transaction.savepoint_rollback(sid)
            return HttpResponse('被别人改了,回滚,秒杀失败')

    else:
        transaction.savepoint_rollback(sid)
        return HttpResponse('库存不足,秒杀失败')
相关推荐
大模型码小白16 分钟前
Spring AI 框架实战:Java 后端集成大模型的架构设计与工程落地
java·人工智能·python·spring
峥嵘life32 分钟前
Android WiFi连接过程 wpa_supplicant 日志分析
android·开发语言·php
BerryS3N37 分钟前
深度解析:从零构建生产级大模型 RAG(检索增强生成)系统全栈指南
开发语言·python·ai
weixin_BYSJ19871 小时前
「课设设计」springboot校园超市助购系统26449 (附源码)
java·javascript·spring boot·python·django·flask·php
今儿敲了吗1 小时前
Python——函数基础
开发语言·笔记·python
半条_虫1 小时前
豆包-网页逆向接口, 免token调用AI
python·ai·shell
kels88991 小时前
单连接动态增减订阅:股票行情API后端降负载实战方案
开发语言·笔记·python·信息可视化·金融
爱吃程序猿的喵1 小时前
LingBot-Map 复现与原理剖析:基于 Geometric Context Transformer 的流式 3D 重建
人工智能·python·深度学习·计算机视觉·3d·transformer
梦想不只是梦与想1 小时前
Python 中的 match-case(模式匹配)
python·match-case
郝同学今天有进步吗2 小时前
构建 LangGraph Code Review Agent(四):文件过滤与 AnalysisPackage 分包
git·python·ai·code review