首页 > 其他分享 >django乐观锁、悲观锁商品秒杀简单demo

django乐观锁、悲观锁商品秒杀简单demo

时间:2023-08-15 16:48:31浏览次数:44  
标签:count transaction demo savepoint django book 秒杀 res id

悲观锁

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁

乐观锁

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁

下面是2个商品秒杀demo:

表模型

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)
# 悲观锁
def skill_pessimistic(request):
    with transaction.atomic():
        sid = transaction.savepoint()
        book = Book.objects.select_for_update().filter(pk=1).first()  # 加行锁 别人只能读不能改
        if book.count > 0:
            Order.objects.create(order_id=str(uuid.uuid4()), order_name="悲观锁抢到的书籍")
            book.count -= 1
            book.save()
            transaction.savepoint_commit(sid)
            return HttpResponse("抢购成功")
        else:
            transaction.savepoint_rollback(sid)
            return HttpResponse("抢购失败")
# 乐观锁
def skill_happy(request):
    with transaction.atomic():
        while True:
            sid = transaction.savepoint()
            book = Book.objects.filter(pk=2).first()
            print('现在的库存为:%s' % book.count)
            if book.count > 0:
                print("现在可以下单")
                Order.objects.create(order_id=str(uuid.uuid4()), order_name="乐观锁抢到的书籍")
                res = Book.objects.filter(pk=2, count=book.count).update(count=book.count - 1)
                """
                  res = Book.objects.filter(pk=2, count=book.count).first()
                  res.count-=1
                  res.save()
                  这种是错误的 实际上是执行了2条sql语句
                  select * form  book  where id=2 and count = ${count}
                  update book set count = ${count} - 1 where id= ${id}
                  
                  
                  只有在执行下面一条语句时候才真正的乐观锁
                  update book set count = ${count} - 1 where id=2 and count = ${count}
                """
                if res < 1:
                    transaction.savepoint_rollback(sid)
                    continue
                transaction.savepoint_commit(sid)
                return HttpResponse("抢购成功")
            else:
                transaction.savepoint_rollback(sid)
                return HttpResponse("抢购失败")

测试demo:

import requests
from threading import Thread


def skill_task(url):
    res = requests.get(f"http://127.0.0.1:8000/{url}/").text
    print(res)


if __name__ == '__main__':
    # 开启五个线程去秒杀商品
    for i in range(5):
        t = Thread(target=skill_task,args="skill_happy")
        t.start()

标签:count,transaction,demo,savepoint,django,book,秒杀,res,id
From: https://www.cnblogs.com/yangyucai/p/17631677.html

相关文章

  • django中使用开启事务的三种方式
    django中使用开启事务的三种方式全局开启事务#settings.pyDATABASES={'default':{#全局开启事务,绑定的是http请求响应整个过程'ATOMIC_REQUESTS':True,}}#局部禁用fromdjango.dbimporttransaction#局......
  • Django templatetags使用
     webapp文件夹下创建templatetags文件夹templates文件夹下创建tags文件夹 templatetags文件夹下创建menu.pyfromdjango.templateimportLibraryregister=Library()@register.inclusion_tag("tags/nb_menu.html")defnb_menu(request):print(555,request.nv_login......
  • seata学习-简单demo入门
    概述学习一个框架,我喜欢从demo中了解该框架所能达到的效果再进行深入地学习。本篇文章将会介绍seata的一个入门使用demo,作为使用seata的入门学习文章。使用案例首先到github中下载一个RM的运行服务,本例中使用的是:https://github.com/seata/seata/releases/download......
  • 社区团购商城拼团秒杀接龙分销团长小程序开源版开发
    社区团购商城拼团秒杀接龙分销团长小程序开源版开发功能介绍:商品管理:增加商品-商品列表-商品分类-商品单/多规格-商品标签订单管理:订单列表-订单挑选-订单导出-订单打印-批量发货-商品评价会员管理:会员列表-会员挑选-会员导出-虚拟会员-会员等级-会员分组-会员分销团长管理:团长列表......
  • Mybatis配置文件的空白模板和联系demo所用到的依赖
    核心配置文件模板<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDConfig3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><envir......
  • Pomelo官方demo ChatofPomelo简析之一——用户登录
    Pomelo官方demoChatofPomelo简析之一——用户登录 官方给的tutorial真是简单明了,简的刚开始学pomelo,压根就不知道代码写在哪。所以还是自己研究研究。首先看服务器端,处理逻辑的主要在game-server/app/servers下。有chat、connector和gate三种类型的服务器。connector:frontend前......
  • django添加装饰器进行登录角色验证
    目的:在用户请求各种接口时验证role字段是否不为user1.创建装饰器  decorators.pyfromdjango.httpimportJsonResponsefromfunctoolsimportwrapsfromutils.tokenimportget_useridfromyshop.modelsimportMyUserdefcheck_role(view_func):@wraps(view_......
  • Django
    1 ① 创建一个新的apppythonmanage.pystartappfirst_app②settings.py注册INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions',&......
  • Python全栈工程师(40:Web框架Django基础)
    Python的WEB框架有Django、Tornado、Flask等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。基础入门教程:http://www.runoob.com/django/django-tutorial.html安装:环境搭建与pycharm的配置django安装及MySQL数据库配......
  • 秒杀库存解决方案
    秒杀库存解决方案电商系统中秒杀是一种常见的业务场景需求,其中核心设计之一就是如何扣减库存。本篇主要分享一些常见库存扣减技术方案,库存扣减设计选择并非一味追求性能更佳,更多的应该考虑根据实际情况来进行架构取舍。在商品购买的过程中,库存的抵扣过程通常包括以下步骤:开启事......