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('库存不足,秒杀失败')
相关推荐
小王子10248 分钟前
设计模式Python版 组合模式
python·设计模式·组合模式
Mason Lin1 小时前
2025年1月22日(网络编程 udp)
网络·python·udp
清弦墨客2 小时前
【蓝桥杯】43697.机器人塔
python·蓝桥杯·程序算法
恋猫de小郭3 小时前
Android Studio 正式版 10 周年回顾,承载 Androider 的峥嵘十年
android·ide·android studio
RZer4 小时前
Hypium+python鸿蒙原生自动化安装配置
python·自动化·harmonyos
CM莫问5 小时前
什么是门控循环单元?
人工智能·pytorch·python·rnn·深度学习·算法·gru
查理零世5 小时前
【算法】回溯算法专题① ——子集型回溯 python
python·算法
圆圆滚滚小企鹅。6 小时前
刷题记录 HOT100回溯算法-6:79. 单词搜索
笔记·python·算法·leetcode
aaaweiaaaaaa6 小时前
php的使用及 phpstorm环境部署
android·web安全·网络安全·php·storm
纠结哥_Shrek6 小时前
pytorch实现文本摘要
人工智能·pytorch·python